Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4296946

TreeModel insertNodeInto/removeNodeFromParent shouldn't chg tree's expand state

XMLWordPrintable

    • Fix Understood
    • generic, x86
    • generic, windows_nt



      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)
      ======================================================================

            Unassigned Unassigned
            kryansunw Kevin Ryan (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Imported:
              Indexed: