Name: krT82822 Date: 12/04/99
java version "1.3beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3beta-O)
Java(TM) HotSpot Client VM (build 1.3beta-O, mixed mode)
/*
Problem: insertNodeInto and removeNodeFromParent of JTreeModel
should not modify collapse/expand state.
Setup: java.version 1.3 beta and 1.2.2, NT 4.0 SP4
java version "1.3beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3beta-O)
Java(TM) HotSpot Client VM (build 1.3beta-O, mixed mode)
Background:
Your article called Understanding the TreeModel says the following:
http://java.sun.com/products/jfc/tsc/articles/jtree/index.html
"Since DefaultMutableTreeNode objects implement swing.tree.MutableTreeNode,
you can avoid the two-step process of making changes and notifying the
model of them by using the following methods, which make changes directly
to the DefaultTreeModel:"
public void insertNodeInto(MutableTreeNode newChild,
MutableTreeNode parent, int index){
public void removeNodeFromParent(MutableTreeNode node) {
Problem
I need to change the sort order of folders. I initially have a tree with
folders Apollo and Skylab. Skylab comes before Apollo i.e. descending.
I need to have Apollo come before Skylab i.e. ascending.
However, when I use removeNodeFromParent and insertNodeInto to achieve
this as recommended by your article, it loses the infomation about the
expansion of Apollo's and Skylab's children. Specifically, initially
the children are expanded and after using removeNodeFromParent and
insertNodeInto, the children are collapsed. This is bad since I only
want to change the order of the folders and preserve the same
expand/collapse state for all nodes.
Ideally, when I remove apolloNode and skylabNode using
removeNodeFromParent, their child node expand/collapse states
should not change. When I then insert apolloNode and
skylabNode using insertNodeInto, insertNodeInto should look at
the expand/collapse state of apolloNode and skylabNode and
insert them using their expand/collapse state. I've tried to
trace through the source code but there are so many places that
it examines and changes the expand/collapse state that I can't
readily find which line of code causes the problem.
Since I need to resort folders frequently in my application,
I need a reliable way to move folders while preserving the
expand/collapse state of all the nodes. Any feedback is appreciated.
Thanks
###@###.###
*/
//Author: John Petrula
//Company: Z-FAST
//Description: ###@###.###
package com.petrula.bug.JTreeInsertRemoveCollapse;
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.event.*;
public class TreeExample extends JTree {
static DefaultMutableTreeNode rootNode = null;
static DefaultMutableTreeNode skylabNode = null;
static DefaultMutableTreeNode apolloNode = null;
public TreeExample() {
rootNode = new DefaultMutableTreeNode();
skylabNode = new DefaultMutableTreeNode("Skylab");
rootNode.add(skylabNode);
apolloNode = new DefaultMutableTreeNode("Apollo");
rootNode.add(apolloNode);
DefaultMutableTreeNode n =
new DefaultMutableTreeNode("11");
apolloNode.add(n);
n.add(new DefaultMutableTreeNode("Neil Armstrong"));
n.add(new DefaultMutableTreeNode("Buzz Aldrin"));
n.add(new DefaultMutableTreeNode("Michael Collins"));
n = new DefaultMutableTreeNode("12");
apolloNode.add(n);
n.add(new DefaultMutableTreeNode("Pete Conrad"));
n.add(new DefaultMutableTreeNode("Alan Bean"));
n.add(new DefaultMutableTreeNode("Richard Gordon"));
n = new DefaultMutableTreeNode("2");
skylabNode.add(n);
n.add(new DefaultMutableTreeNode("Pete Conrad"));
n.add(new DefaultMutableTreeNode("Joseph Kerwin"));
n.add(new DefaultMutableTreeNode("Paul Weitz"));
n = new DefaultMutableTreeNode("3");
skylabNode.add(n);
n.add(new DefaultMutableTreeNode("Alan Bean"));
n.add(new DefaultMutableTreeNode("Owen Garriott"));
n.add(new DefaultMutableTreeNode("Jack Lousma"));
this.setModel(new DefaultTreeModel(rootNode));
expandAll((TreeNode)getModel().getRoot());
}
public void expandAll(TreeNode tNode) {
TreePath tp = new TreePath(((DefaultMutableTreeNode)tNode).getPath());
expandPath(tp);
int i=0;
for(; i<tNode.getChildCount(); i++)
expandAll(tNode.getChildAt(i));
}
public static void main(String[] args) {
try {
// Windows L&F
UIManager.setLookAndFeel
("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
// Create JFrame
JFrame myFrame = new JFrame("Tree Bug");
myFrame.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
TreeExample tree = new TreeExample();
myFrame.getContentPane().add(new JScrollPane(tree));
myFrame.pack();
myFrame.setVisible(true);
Thread.sleep(5000);
DefaultTreeModel treeModel = (DefaultTreeModel)tree.getModel();
treeModel.removeNodeFromParent(apolloNode);
treeModel.removeNodeFromParent(skylabNode);
treeModel.insertNodeInto(apolloNode, rootNode, 0);
treeModel.insertNodeInto(skylabNode, rootNode, 1);
}
catch( Exception e) {
e.printStackTrace();
}
}
}
(Review ID: 98619)
======================================================================
Name: krC82822 Date: 12/14/2000
JavaTM 2 Platform, Standard Edition,?v1.2.2
java version "1.2.2"
Classic VM (build JDK-1.2.2-001, native threads, symcjit)
REF: See existing Bug ID: 4296946
The problem is described well in the above bug report and I report it again
because of the following, anonymous comment from the JTree.java code,
treeStructureChanged(TreeModelEvent e) method, which suggests that the problem
is known about and can, perhaps be fixed:
// NOTE: If I change this to NOT remove the descendants
// and update BasicTreeUIs treeStructureChanged method
// to update descendants in response to a treeStructureChanged
// event, all the children of the event won't collapse!
In my case, I have the following tree structure (for example) in the display:
body
-arm
-hand
-finger
-nail
If I use our Java interface to add another arm to the body, the following is
what I get:
body
+arm
+arm
Where '-' represents expanded and '+' represents collapsed tree structure.
Despite the evaluation comments for the above bug report, I maintain that this
is a real problem that should be fixed in the JTree code and not by application
work around.
(Review ID: 113781)
======================================================================