mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GT-3256 Fixed bugs related to recent GTree changes.
This commit is contained in:
parent
b0609a1cb3
commit
67f0318be9
14 changed files with 460 additions and 210 deletions
|
@ -58,7 +58,14 @@ abstract class CoreGTreeNode implements Cloneable {
|
|||
* @return the parent of this node.
|
||||
*/
|
||||
public final GTreeNode getParent() {
|
||||
return parent;
|
||||
GTreeNode localParent = parent;
|
||||
|
||||
// Do not return the GTree's fake root node parent. From the client's perspective,
|
||||
// this node does not exist.
|
||||
if (localParent instanceof GTreeRootParentNode) {
|
||||
return null;
|
||||
}
|
||||
return localParent;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -166,6 +173,22 @@ abstract class CoreGTreeNode implements Cloneable {
|
|||
}
|
||||
}
|
||||
|
||||
final void disposeClones() {
|
||||
List<GTreeNode> oldChildren;
|
||||
synchronized (this) {
|
||||
oldChildren = children;
|
||||
children = null;
|
||||
parent = null;
|
||||
}
|
||||
|
||||
if (oldChildren != null) {
|
||||
for (GTreeNode node : oldChildren) {
|
||||
node.disposeClones();
|
||||
}
|
||||
oldChildren.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the node is in the process of loading its children.
|
||||
* See {@link GTreeSlowLoadingNode}
|
||||
|
@ -191,6 +214,19 @@ abstract class CoreGTreeNode implements Cloneable {
|
|||
return !isInProgress(children);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the GTree that this node is attached to
|
||||
* @return the GTree that this node is attached to
|
||||
*/
|
||||
public GTree getTree() {
|
||||
// here we want to use the parent variable, not getParent() which
|
||||
// filters out GTreeRootParentNodes which is what actually can provide the tree
|
||||
if (parent != null) {
|
||||
return parent.getTree();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the node is in the process of loading its children. For nodes
|
||||
* that directly extend GTreeNode, this is always false. See {@link GTreeSlowLoadingNode}
|
||||
|
|
|
@ -765,10 +765,11 @@ public class GTree extends JPanel implements BusyListener {
|
|||
}
|
||||
|
||||
void setFilteredRootNode(GTreeNode filteredRootNode) {
|
||||
filteredRootNode.setParent(rootParent);
|
||||
GTreeNode currentRoot = (GTreeNode) model.getRoot();
|
||||
model.setRootNode(filteredRootNode);
|
||||
if (currentRoot != realRootNode) {
|
||||
currentRoot.dispose();
|
||||
currentRoot.disposeClones();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -776,7 +777,7 @@ public class GTree extends JPanel implements BusyListener {
|
|||
GTreeNode currentRoot = (GTreeNode) model.getRoot();
|
||||
model.setRootNode(realRootNode);
|
||||
if (currentRoot != realRootNode) {
|
||||
currentRoot.dispose();
|
||||
currentRoot.disposeClones();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,27 +50,27 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
|
||||
/**
|
||||
* Returns the name of the node to be displayed in the tree
|
||||
* @return the name of the node.
|
||||
* @return the name of the node
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
/**
|
||||
* Returns the Icon to be displayed for this node in the tree.
|
||||
* @param expanded true if the node is expanded.
|
||||
* @return the icon to be displayed for this node in the tree.
|
||||
* Returns the Icon to be displayed for this node in the tree
|
||||
* @param expanded true if the node is expanded
|
||||
* @return the icon to be displayed for this node in the tree
|
||||
*/
|
||||
public abstract Icon getIcon(boolean expanded);
|
||||
|
||||
/**
|
||||
* Returns the string to be displayed as a tooltip when the user
|
||||
* hovers the mouse on this node in the tree.
|
||||
* @return the tooltip to be displayed.
|
||||
* hovers the mouse on this node in the tree
|
||||
* @return the tooltip to be displayed
|
||||
*/
|
||||
public abstract String getToolTip();
|
||||
|
||||
/**
|
||||
* Returns true if this node never has children.
|
||||
* @return true if this node is a leaf.
|
||||
* Returns true if this node never has children
|
||||
* @return true if this node is a leaf
|
||||
*/
|
||||
public abstract boolean isLeaf();
|
||||
|
||||
|
@ -82,7 +82,7 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
/**
|
||||
* Adds the given node as a child to this node. Note: this method may be inefficient so if you
|
||||
* have many nodes to add, you should use either {@link #addNodes(List)} or {@link #setChildren(List)}
|
||||
* @param node the node to add as a child.
|
||||
* @param node the node to add as a child
|
||||
*/
|
||||
public void addNode(GTreeNode node) {
|
||||
children().add(node);
|
||||
|
@ -91,8 +91,8 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds the given nodes as children to this node.
|
||||
* @param nodes the nodes to add.
|
||||
* Adds the given nodes as children to this node
|
||||
* @param nodes the nodes to add
|
||||
*/
|
||||
public void addNodes(List<GTreeNode> nodes) {
|
||||
for (GTreeNode node : nodes) {
|
||||
|
@ -103,9 +103,9 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds the given node at the given index as a child to this node.
|
||||
* @param index the index to place the node.
|
||||
* @param node the node to add as a child of this node.
|
||||
* Adds the given node at the given index as a child to this node
|
||||
* @param index the index to place the node
|
||||
* @param node the node to add as a child of this node
|
||||
*/
|
||||
public void addNode(int index, GTreeNode node) {
|
||||
children().add(index, node);
|
||||
|
@ -126,8 +126,8 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
|
||||
/**
|
||||
* Returns the number of <b>visible</b> children of this node. Does not include
|
||||
* nodes that are current filtered out.
|
||||
* @return the number of <b>visible</b> children of this node.
|
||||
* nodes that are current filtered out
|
||||
* @return the number of <b>visible</b> children of this node
|
||||
*/
|
||||
public int getChildCount() {
|
||||
return children().size();
|
||||
|
@ -135,8 +135,8 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
|
||||
/**
|
||||
* Returns the child node of this node with the given name.
|
||||
* @param name the name of the child to be returned.
|
||||
* @return the child with the given name.
|
||||
* @param name the name of the child to be returned
|
||||
* @return the child with the given name
|
||||
*/
|
||||
public GTreeNode getChild(String name) {
|
||||
for (GTreeNode node : children()) {
|
||||
|
@ -150,8 +150,8 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
/**
|
||||
* Returns the child node at the given index. Returns null if the index is out of
|
||||
* bounds.
|
||||
* @param index the index of the child to be returned.
|
||||
* @return the child at the given index.
|
||||
* @param index the index of the child to be returned
|
||||
* @return the child at the given index
|
||||
*/
|
||||
public GTreeNode getChild(int index) {
|
||||
return children().get(index);
|
||||
|
@ -160,7 +160,7 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
/**
|
||||
* Returns the total number of nodes in the subtree rooted at this node. Leaf
|
||||
* nodes return 1.
|
||||
* @return the number of nodes from this node downward.
|
||||
* @return the number of nodes from this node downward
|
||||
*/
|
||||
public int getNodeCount() {
|
||||
int count = 1;
|
||||
|
@ -171,8 +171,8 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of leaf nodes in the subtree from this node.
|
||||
* @return the total number of leaf nodes in the subtree from this node.
|
||||
* Returns the total number of leaf nodes in the subtree from this node
|
||||
* @return the total number of leaf nodes in the subtree from this node
|
||||
*/
|
||||
public int getLeafCount() {
|
||||
int count = 0;
|
||||
|
@ -183,8 +183,8 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the index of this node within its parent node.
|
||||
* @return the index of this node within its parent node.
|
||||
* Returns the index of this node within its parent node
|
||||
* @return the index of this node within its parent node
|
||||
*/
|
||||
public int getIndexInParent() {
|
||||
GTreeNode parent = getParent();
|
||||
|
@ -197,16 +197,16 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
/**
|
||||
* Returns the index of the given node within this node. -1 is returned
|
||||
* if the node is not a child of this node.
|
||||
* @param node whose index we want.
|
||||
* @return the index of the given node within this node.
|
||||
* @param node whose index we want
|
||||
* @return the index of the given node within this node
|
||||
*/
|
||||
public int getIndexOfChild(GTreeNode node) {
|
||||
return children().indexOf(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TreePath for this node.
|
||||
* @return the TreePath for this node.
|
||||
* Returns the TreePath for this node
|
||||
* @return the TreePath for this node
|
||||
*/
|
||||
public TreePath getTreePath() {
|
||||
return new TreePath(getPathToRoot(this, 0));
|
||||
|
@ -230,8 +230,8 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
}
|
||||
|
||||
/**
|
||||
* Remove the given node from this node.
|
||||
* @param node the to be removed.
|
||||
* Remove the given node from this node
|
||||
* @param node the to be removed
|
||||
*/
|
||||
public void removeNode(GTreeNode node) {
|
||||
if (!isLoaded()) {
|
||||
|
@ -240,13 +240,13 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
List<GTreeNode> children = children();
|
||||
if (children.remove(node)) {
|
||||
node.setParent(null);
|
||||
fireNodeStructureChanged(this);
|
||||
fireNodeRemoved(this, node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the children on this node. Any existing current children will be dispose.
|
||||
* @param childList this list of nodes to be set as children of this node.
|
||||
* @param childList this list of nodes to be set as children of this node
|
||||
*/
|
||||
public void setChildren(List<GTreeNode> childList) {
|
||||
doSetChildren(childList);
|
||||
|
@ -256,7 +256,7 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
/**
|
||||
* Returns true if the given node is a child of this node or one of its children.
|
||||
* @param node the potential descendant node to check
|
||||
* @return true if the given node is a child of this node or one of its children.
|
||||
* @return true if the given node is a child of this node or one of its children
|
||||
*/
|
||||
public boolean isAncestor(GTreeNode node) {
|
||||
GTreeNode nodeParent = node.getParent();
|
||||
|
@ -273,7 +273,7 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
* Notification method called when a cell editor completes editing to notify this
|
||||
* node that its value has changed. If you override this method you must also override
|
||||
* {@link #isEditable()}.
|
||||
* @param newValue the new value provided by the cell editor.
|
||||
* @param newValue the new value provided by the cell editor
|
||||
* @see #isEditable()
|
||||
*/
|
||||
public void valueChanged(Object newValue) {
|
||||
|
@ -284,7 +284,7 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
* Returns true if this node is allowed to be edited in the tree. You must override this
|
||||
* method to allow a node to be edited. You must also override {@link #valueChanged(Object)}
|
||||
* to handle the result of the edit.
|
||||
* @return true if this node is allowed to be edited in the tree.
|
||||
* @return true if this node is allowed to be edited in the tree
|
||||
* @see #valueChanged(Object)
|
||||
*/
|
||||
public boolean isEditable() {
|
||||
|
@ -293,8 +293,8 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
|
||||
/**
|
||||
* Returns the rootNode for this tree or null if there is no parent path to a
|
||||
* GTRootNode.
|
||||
* @return the rootNode for this tree.
|
||||
* GTRootNode
|
||||
* @return the rootNode for this tree
|
||||
*/
|
||||
public GTreeNode getRoot() {
|
||||
GTreeNode myParent = getParent();
|
||||
|
@ -312,18 +312,6 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
return getRoot() == this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the GTree that this node is attached to
|
||||
* @return the GTree that this node is attached to
|
||||
*/
|
||||
public GTree getTree() {
|
||||
GTreeNode parent = getParent();
|
||||
if (parent != null) {
|
||||
return parent.getTree();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a filtered copy of this node and its children.
|
||||
* <P>
|
||||
|
@ -331,12 +319,12 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
* NOTE: the filter will only be applied to a nodes children if they are loaded. So to
|
||||
* perform a filter on all the nodes in the tree, the {@link #loadAll(TaskMonitor)} should
|
||||
* be called before the filter call.
|
||||
* @param filter the filter being applied.
|
||||
* @param monitor a TaskMonitor for tracking the progress and cancelling.
|
||||
* @param filter the filter being applied
|
||||
* @param monitor a TaskMonitor for tracking the progress and cancelling
|
||||
* @return A copy of this node and its children that matches the filter or null
|
||||
* if this node and none of its children match the filter.
|
||||
* @throws CancelledException if the operation is cancelled via the TaskMonitor.
|
||||
* @throws CloneNotSupportedException if any nodes in the tree explicitly prevents cloning.
|
||||
* if this node and none of its children match the filter.
|
||||
* @throws CancelledException if the operation is cancelled via the TaskMonitor
|
||||
* @throws CloneNotSupportedException if any nodes in the tree explicitly prevents cloning
|
||||
*/
|
||||
|
||||
public GTreeNode filter(GTreeFilter filter, TaskMonitor monitor)
|
||||
|
@ -367,8 +355,8 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
* is fully loaded. Nodes that are already loaded (including normal nodes which are always loaded)
|
||||
* do nothing except recursively call {@link #loadAll(TaskMonitor)} on their children.
|
||||
* @param monitor the TaskMonitor to monitor progress and provide cancel checking
|
||||
* @return the total number of nodes in the subtree of this node.
|
||||
* @throws CancelledException if the operation is cancelled using the monitor.
|
||||
* @return the total number of nodes in the subtree of this node
|
||||
* @throws CancelledException if the operation is cancelled using the monitor
|
||||
*/
|
||||
public int loadAll(TaskMonitor monitor) throws CancelledException {
|
||||
List<GTreeNode> children = children();
|
||||
|
@ -403,43 +391,18 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
}
|
||||
|
||||
/**
|
||||
* Notifies the tree that the node has different children. This method
|
||||
* @param node the node that has changed.
|
||||
*/
|
||||
public void fireNodeStructureChanged(GTreeNode node) {
|
||||
GTree tree = getTree();
|
||||
if (tree != null) {
|
||||
Swing.runNow(() -> tree.getModel().fireNodeStructureChanged(node));
|
||||
tree.refilterLater();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the tree that a node has changed.
|
||||
* @param parentNode the node that contains the node that was changed.
|
||||
* @param node the that changed.
|
||||
*/
|
||||
public void fireNodeChanged(GTreeNode parentNode, GTreeNode node) {
|
||||
GTree tree = getTree();
|
||||
if (tree != null) {
|
||||
Swing.runNow(() -> tree.getModel().fireNodeDataChanged(parentNode, node));
|
||||
tree.refilterLater();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stream of the GTree nodes in the subtree of this node.
|
||||
* Returns a stream of the GTree nodes in the subtree of this node
|
||||
* @param depthFirst if true, the nodes will be streamed in depth-first order, otherwise breadth-first order
|
||||
* @return a stream of the GTree nodes in the subtree of this node.
|
||||
* @return a stream of the GTree nodes in the subtree of this node
|
||||
*/
|
||||
public Stream<GTreeNode> stream(boolean depthFirst) {
|
||||
return CollectionUtils.asStream(iterator(depthFirst));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator of the GTree nodes in the subtree of this node.
|
||||
* Returns an iterator of the GTree nodes in the subtree of this node
|
||||
* @param depthFirst if true, the nodes will be returned in depth-first order, otherwise breadth-first order
|
||||
* @return an iterator of the GTree nodes in the subtree of this node.
|
||||
* @return an iterator of the GTree nodes in the subtree of this node
|
||||
*/
|
||||
public Iterator<GTreeNode> iterator(boolean depthFirst) {
|
||||
if (depthFirst) {
|
||||
|
@ -462,6 +425,31 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the tree that the node has different children. This method
|
||||
* @param node the node that has changed.
|
||||
*/
|
||||
public void fireNodeStructureChanged(GTreeNode node) {
|
||||
GTree tree = getTree();
|
||||
if (tree != null) {
|
||||
Swing.runNow(() -> tree.getModel().fireNodeStructureChanged(node));
|
||||
tree.refilterLater();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the tree that a node has changed
|
||||
* @param parentNode the node that contains the node that was changed
|
||||
* @param node the that changed
|
||||
*/
|
||||
public void fireNodeChanged(GTreeNode parentNode, GTreeNode node) {
|
||||
GTree tree = getTree();
|
||||
if (tree != null) {
|
||||
Swing.runNow(() -> tree.getModel().fireNodeDataChanged(parentNode, node));
|
||||
tree.refilterLater();
|
||||
}
|
||||
}
|
||||
|
||||
protected void fireNodeAdded(GTreeNode parentNode, GTreeNode newNode) {
|
||||
GTree tree = getTree();
|
||||
if (tree != null) {
|
||||
|
@ -470,13 +458,12 @@ public abstract class GTreeNode extends CoreGTreeNode implements Comparable<GTre
|
|||
}
|
||||
}
|
||||
|
||||
protected void fireNodeRemoved(GTreeNode parentNode, GTreeNode removedNode,
|
||||
int deletedChildIndex) {
|
||||
protected void fireNodeRemoved(GTreeNode parentNode, GTreeNode removedNode) {
|
||||
|
||||
GTree tree = getTree();
|
||||
if (tree != null) {
|
||||
Swing.runNow(
|
||||
() -> tree.getModel().fireNodeRemoved(parentNode, removedNode, deletedChildIndex));
|
||||
() -> tree.getModel().fireNodeRemoved(parentNode, removedNode));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import javax.swing.event.TreeModelListener;
|
|||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import docking.widgets.tree.GTree;
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import ghidra.util.SystemUtilities;
|
||||
|
||||
|
@ -70,8 +71,15 @@ public class GTreeModel implements TreeModel {
|
|||
|
||||
@Override
|
||||
public Object getChild(Object parent, int index) {
|
||||
GTreeNode gTreeParent = (GTreeNode) parent;
|
||||
return gTreeParent.getChild(index);
|
||||
try {
|
||||
GTreeNode gTreeParent = (GTreeNode) parent;
|
||||
return gTreeParent.getChild(index);
|
||||
}
|
||||
catch (IndexOutOfBoundsException e) {
|
||||
// children must have be changed outside of swing thread, should get another event
|
||||
// to fix things up, so just return an in-progress node
|
||||
return new InProgressGTreeNode();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -107,6 +115,14 @@ public class GTreeModel implements TreeModel {
|
|||
SystemUtilities.assertThisIsTheSwingThread(
|
||||
"GTreeModel.fireNodeStructuredChanged() must be " + "called from the AWT thread");
|
||||
|
||||
GTreeNode node = convertToViewNode(changedNode);
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
if (node != changedNode) {
|
||||
node.setChildren(null);
|
||||
}
|
||||
|
||||
TreeModelEvent event = new TreeModelEvent(this, changedNode.getTreePath());
|
||||
for (TreeModelListener listener : listeners) {
|
||||
listener.treeStructureChanged(event);
|
||||
|
@ -141,15 +157,21 @@ public class GTreeModel implements TreeModel {
|
|||
|
||||
TreeModelEvent event;
|
||||
if (parentNode == null) { // special case when root node changes.
|
||||
event = new TreeModelEvent(this, changedNode.getTreePath(), null, null);
|
||||
event = new TreeModelEvent(this, root.getTreePath(), null, null);
|
||||
}
|
||||
else {
|
||||
int indexInParent = changedNode.getIndexInParent();
|
||||
GTreeNode node = convertToViewNode(changedNode);
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int indexInParent = node.getIndexInParent();
|
||||
if (indexInParent < 0) {
|
||||
return; // node is filtered
|
||||
return;
|
||||
}
|
||||
event =
|
||||
new TreeModelEvent(this, parentNode.getTreePath(), new int[] { indexInParent },
|
||||
new TreeModelEvent(this, node.getParent().getTreePath(),
|
||||
new int[] { indexInParent },
|
||||
new Object[] { changedNode });
|
||||
}
|
||||
for (TreeModelListener listener : listeners) {
|
||||
|
@ -164,30 +186,33 @@ public class GTreeModel implements TreeModel {
|
|||
SystemUtilities.assertThisIsTheSwingThread(
|
||||
"GTreeModel.fireNodeAdded() must be " + "called from the AWT thread");
|
||||
|
||||
int indexInParent = newNode.getIndexInParent();
|
||||
if (indexInParent < 0) {
|
||||
GTreeNode node = convertToViewNode(parentNode);
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
TreeModelEvent event =
|
||||
new TreeModelEvent(this, parentNode.getTreePath(), new int[] { indexInParent },
|
||||
new Object[] { newNode });
|
||||
TreeModelEvent event = new TreeModelEvent(this, node.getTreePath());
|
||||
for (TreeModelListener listener : listeners) {
|
||||
listener.treeNodesInserted(event);
|
||||
listener.treeStructureChanged(event);
|
||||
}
|
||||
}
|
||||
|
||||
public void fireNodeRemoved(final GTreeNode parentNode, final GTreeNode removedNode,
|
||||
final int oldIndexInParent) {
|
||||
public void fireNodeRemoved(final GTreeNode parentNode, final GTreeNode removedNode) {
|
||||
|
||||
SystemUtilities.assertThisIsTheSwingThread(
|
||||
"GTreeModel.fireNodeRemoved() must be " + "called from the AWT thread");
|
||||
|
||||
TreeModelEvent event =
|
||||
new TreeModelEvent(this, parentNode.getTreePath(), new int[] { oldIndexInParent },
|
||||
new Object[] { removedNode });
|
||||
GTreeNode node = convertToViewNode(parentNode);
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
if (node != parentNode) {
|
||||
node.removeNode(removedNode);
|
||||
}
|
||||
|
||||
TreeModelEvent event = new TreeModelEvent(this, node.getTreePath());
|
||||
for (TreeModelListener listener : listeners) {
|
||||
listener.treeNodesRemoved(event);
|
||||
listener.treeStructureChanged(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,4 +223,15 @@ public class GTreeModel implements TreeModel {
|
|||
public void setEventsEnabled(boolean b) {
|
||||
eventsEnabled = b;
|
||||
}
|
||||
|
||||
private GTreeNode convertToViewNode(GTreeNode node) {
|
||||
if (node.getRoot() == root) {
|
||||
return node;
|
||||
}
|
||||
GTree tree = root.getTree();
|
||||
if (tree != null) {
|
||||
return tree.getViewNodeForPath(node.getTreePath());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue