Name: yyT116575 Date: 11/30/2000
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)
When a JTree is created with a DefaultTreeModel you can programmatically add
DefaultMutableTreeNodes and fire the appropriate events by calling
DefaultTreeModel.nodesWereInserted(). In some cases, the JTree does not update
appropriately. In particular, when the parent node has no children it appears
to fail.
>1.Exact steps to reproduce the problem.
Run the test program below. Clicking 'add' adds a single node at index 0 below
the root, and calls nodesWereInserted appropriately. Clicking 'delete' removes
a node from index 0 (if one exists) and calls nodesWereRemoved. Clicking
'refresh' calls nodeStructureChanged on the root node.
Click 'add' three or four times to add new nodes to the root node. Note that
the root node icon changes to indicate that children are present, but no
children are visible. Now click refresh--there's the children! Now click add
and delete a few times to see that the child nodes are properly appearing and
disappearing.
Delete all of the children by pressing 'delete' until they're all gone. Now hit
'add'. Note that this time a child node appears. Remove all the children again
and hit 'refresh'. Now hitting add fails to display the children, although the
icon change again indicates they are there--just like when the tree was created.
End result: sometimes nodesWereInserted() properly updates the JTree, sometimes
it doesn't.
>2.Java SOURCE CODE that demonstrates the problem, if possible.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
public class TestTree extends JFrame {
protected JTree tree = null;
protected DefaultMutableTreeNode rootNode = null;
protected DefaultTreeModel model = null;
public TestTree() {
JPanel _panel = new JPanel(new BorderLayout());
rootNode = new DefaultMutableTreeNode("Root");
tree = new JTree(rootNode);
model = (DefaultTreeModel)tree.getModel();
_panel.add(new JScrollPane(tree), BorderLayout.CENTER);
JPanel _buttonPanel = new JPanel();
JButton _button = new JButton("Add");
_button.addActionListener(new HandleAdd());
_buttonPanel.add(_button);
_button = new JButton("Delete");
_button.addActionListener(new HandleDelete());
_buttonPanel.add(_button);
_button = new JButton("Refresh");
_button.addActionListener(new HandleRefresh());
_buttonPanel.add(_button);
_panel.add(_buttonPanel, BorderLayout.SOUTH);
getContentPane().add(_panel);
setSize(400, 400);
}
protected class HandleAdd implements ActionListener {
public void actionPerformed(ActionEvent pAE) {
int[] _iIndices = new int[1];
DefaultMutableTreeNode _node = new DefaultMutableTreeNode("Add");
rootNode.insert(_node, 0);
_iIndices[0] = 0;
model.nodesWereInserted(rootNode, _iIndices);
}
}
protected class HandleDelete implements ActionListener {
public void actionPerformed(ActionEvent pAE) {
if (rootNode.getChildCount() < 1) return;
DefaultMutableTreeNode _nodeChild = (DefaultMutableTreeNode)rootNode.getChildAt(0);
int _iIndices[] = new int[1];
_iIndices[0] = 0;
rootNode.remove(_nodeChild);
Object _objObjects[] = new Object[1];
_objObjects[0] = _nodeChild;
model.nodesWereRemoved(rootNode, _iIndices, _objObjects);
}
}
protected class HandleRefresh implements ActionListener {
public void actionPerformed(ActionEvent pAE) {
model.nodeStructureChanged(rootNode);
}
}
public static void main(String[] pArgs) {
TestTree _tt = new TestTree();
_tt.setVisible(true);
}
}
(Review ID: 111631)
======================================================================