SetUserObject vs getUserObject in MutableTreeNode

Does anyone know why the MutableTreeNode interface has a setUserObject (Object obj) method stub, but not a corresponding getUserObject (Object obj) stub, yet the DefaultMutableTreeNode implementation does have this method?
It means I have to cast and tie my code to a specific implementation (DefaultMutableTreeNode) to read the user object in a tree node when casting to the interface would seem a lot more robust... apart from anything else you'd think any defensive interface design would stop someone setting objects rather than getting them...

This is weird and probably wrong/bad design

Similar Messages

  • JTree nodes not updating

    I have a JTree which the nodes are changed from within an actionPerfomed method. However, they are not updating on the screen until a user clicks on a node. Also, the length of the selection box does not change on the tree, so text can be clipped. The code from my actionPerformed is as follows
    DefaultMutableTreeNode node = findObjectInTree( event.getOriginalObject() );
    if ( node != null ) {
    node.setUserObject( event.getObject() );
    DefaultTreeModel model = ( DefaultTreeModel ) titleTree.getModel();
    model.nodeChanged( node );
    TreePath path = new TreePath( node.getPath() );
    titleTree.scrollPathToVisible( path );
    titleTree.setSelectionPath( path );

    I'm not sure what that 'event.getOriginalObject()' stuuf is, but maybe this will helpimport java.awt.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    import java.util.*;
    public class Test3 extends JFrame implements Runnable {
      Vector nodes = new Vector();
      DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
      DefaultTreeModel dtm = new DefaultTreeModel(root);
      JTree jt = new JTree(dtm);
      Random r = new Random();
      int nodeCount=0;
      public Test3() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container content = getContentPane();
        addNodes(root,0);
        content.add(new JScrollPane(jt), BorderLayout.CENTER);
        setSize(400, 400);
        new Thread(this).start();
      private void addNodes(DefaultMutableTreeNode parent, int level) {
        int cnt = r.nextInt(3)+5-level;
        for (int i=0; i<cnt; i++) {
          DefaultMutableTreeNode node = new DefaultMutableTreeNode("Node"+nodeCount++);
          parent.add(node);
          nodes.add(node);
          addNodes(node, level+1);
      public static void main(String[] args) { new Test3().setVisible(true); }
      public void run() {
        while (true) {
          try { Thread.sleep(2000); } catch (Exception e) {}
          DefaultMutableTreeNode randNode = (DefaultMutableTreeNode)
                                         nodes.get(r.nextInt(nodes.size()));
          randNode.setUserObject(randNode.getUserObject()+"!");
          dtm.nodeChanged(randNode);
          TreePath tp = new TreePath(randNode.getPath());
          jt.scrollPathToVisible(tp);
          jt.setSelectionPath(tp);
    }

  • Rename jtree (impossible)

    hi
    i have a very intricate probleme.
    i have a jtree and i wanna rename some nodes.
    firstable i have set :
    tree.seteditable(true);
    so when i click tree times on a node i can change is value; great !
    but when i finish to type the inputtext i wanna validate it with enter key, it means i wanna have a tiny code for the validation which will be executed just after i type the enter key.
    PLEASE HELP ME ABOUT THIS STUFF
    THANKS

    You have a couple of options.
    You can add a TreeModelListener to the tree model so that when a value in the tree model is changed, you can react to it. Whenever the tree finishes editing a node it will fire a treeNodesChanged() event. You can listen for those events, and then take action based on if you liked the change or not.
    or...
    You can create your own tree node (or subclass) used in the DefaultTreeModel and put your own validation logic in the setUserObject() method of the MutableTreeNode.
    This 2nd one is the best way to go, because then the data underlying the tree node doesn't actually get changed unless you ok it. Using the listener method above, you would have to change the node's value back if you didn't like it, and then force the user to try again.

  • "class Junk extends Hashtable .. implements MutableTreeNode"  seems flakey

    If I add 3 child nodes to one root and then use DefaultTreeModel(root) in a JTree using this very basic implementation of MutableTreeNode, I can see all three children. Just by merely adding "extends Hashtable.." only the last child shows & blank space is shown in place of the other two (the lines are missing for them as well). Can anybody explain this? For now, I no longer am extending Hashtable - after several hours of figuring out what my problem was.
    Regards,
    Monty
    package temp;
    import java.util.Enumeration;
    import java.util.Hashtable;
    import java.util.Vector;
    import javax.swing.tree.MutableTreeNode;
    import javax.swing.tree.TreeNode;
    public class Node  implements MutableTreeNode {
         final Vector<Node> v = new Vector<Node>();
         final String name;
         Node parent;
         Node(String n) {
              name = n;
         public void insert(MutableTreeNode child, int index) {
              // TODO Auto-generated method stub
         public void remove(int index) {
              // TODO Auto-generated method stub
         public void remove(MutableTreeNode node) {
              // TODO Auto-generated method stub
         public void removeFromParent() {
              // TODO Auto-generated method stub
         public void setParent(MutableTreeNode newParent) {
              parent = (Node) newParent;
         public void setUserObject(Object object) {
         public Enumeration children() {
              return v.elements();
         public String toString() {
              return name;
         public boolean getAllowsChildren() {
              return true;
         public TreeNode getChildAt(int childIndex) {
              // TODO Auto-generated method stub
              return v.get(childIndex);
         public int getChildCount() {
              return v.size();
         public int getIndex(TreeNode node) {
              return v.indexOf(node);
         public TreeNode getParent() {
              return parent;
         public boolean isLeaf() {
              return v.isEmpty();
    }

    Define equals() and hashCode() methods appropriately in your custom tree node class otherwise the methods from Hashtable, which would be empty in your tested code, are used resulting a weird JTree object. See the API documentation for the TreeModel interface for the issue.
    When you post a code on a public forum, you should post an SSCCE(http://homepage1.nifty.com/algafield/sscce.html) for making forum friends' helping work lighter.

  • Why im getting too long time in getting response from server in RMI???

    I'm using RMI architecture. On my server side I put this method getRubricHierarchy() which returns the ArrayList of Test class objects. everything is working properly fine.
    Im getting response properly, problem is its taking very long time in getting the response. method populate and create ArrayList in 0 second at server side but its taking more than 20 seconds to get response at client side.
    My arraylist size is 30,000.
    Any suggestions to reduce the time.
    below you can see the code.
    public List<Test> getRubricHierarchy(String strTree,String gblCombinedRepSectionID,String gblCompleteRepSectionID,String gblCompleteRepertoryID,Map authMap) {
            Connection con=null;
              ResultSet rs = null;
              List<Test> l = new ArrayList<Test>();
              List allList = new ArrayList();
              con = createDBCon();
              rs = con.createStatement().executeQuery("select * from rubric where sectionid='"+gblCombinedRepSectionID+"' order by orders");
              Map parentMap = new HashMap();
              while (rs.next()) {
                   Test rNode = new Test();
                String rubrid = rs.getString("id");
                   final String desc = rs.getString("name");
                   rNode.setRubricName(desc);
                   rNode.setRubricID(rubrid);
                   rNode.setAuthor(rs.getString("repid"));
                   final int levlId = rs.getInt("levelid");
                   rNode.setRubLevel(levlId);
                   rNode.setCrossRef(rs.getString("CROSSREFERENCE"));
                   final String parentID = rs.getString("PARENTID");
                   rNode.setParentID(parentID);
                   rNode.setSectionID(rs.getString("sectionid"));
                   if (parentID.equals("0")) {
                        l.add(rNode);
                   allList.add(rNode);
                   List rmdyLst = (List) parentMap.get(parentID);
                   if (rmdyLst == null) {
                        rmdyLst = new ArrayList();
                        parentMap.put(parentID, rmdyLst);
                   rmdyLst.add(rNode);
              rs.close();
              for (Iterator iterator = allList.iterator(); iterator.hasNext();) {
                   Test rNodes = (Test) iterator.next();
                   List remdyLst = (List) parentMap.get(rNodes.getRubricID());
                   if (remdyLst != null) {
                        rNodes.setChildren(remdyLst);
                        for (Iterator iterator2 = remdyLst.iterator(); iterator2.hasNext();) {
                             Test rn = (Test) iterator2.next();
                             rn.setParent(rNodes);
            }catch(Exception e){
                e.printStackTrace();
              return l;
         }here is my Test Class
    public class Test implements  Serializable,Cloneable , MutableTreeNode{
            private String strRubricID,strOldRubricID,strRubricName,strCrossRef,Author,strParentID,strSectionID;
            private int rubLevel;
            private List remedyList;
            private List children = new ArrayList();
            private Test parent;
            private int order;
            private String AuthorName="";
            private String abbr;
            private String treeType="";
            private int noRem=-1;
            private boolean isAddAsChild=false;
            private String strRubricHie="";
            private String user="";
            public static final Enumeration<TreeNode> EMPTY_ENUMERATION = new Enumeration() {
                public boolean hasMoreElements() {
                    return false;
                public TreeNode nextElement() {
                    throw new NoSuchElementException("No more elements");
            public Test(){
            public void setUser(String user){
                this.user = user;
            public String getUser(){
                return user;
            public void setRubricHierarchy(String s){
                this.strRubricHie=s;
            public String getRubricHierarchy(){
                return strRubricHie;
            public Test(String treeType){
                this.treeType = treeType;
            public void setAddAsChild(boolean b){
                this.isAddAsChild=b;
            public boolean isAddAsChild(){
                return isAddAsChild;
            public Test getUserObject(){
                return this;
            public  void setRubricID(String id){
                this.strRubricID = id;
            public  String getRubricID(){
                return strRubricID ;
            public  void setOldRubricID(String id){
                this.strOldRubricID = id;
            public  String getOldRubricID(){
                return strOldRubricID ;
            public  void setParent(Test r){
                this.parent = r;
            public  Test getParent(){
                return parent;
            public  void setParentID(String id){
                this.strParentID = id;
            public  String getParentID(){
                return strParentID;
            public  void setSectionID(String id){
                this.strSectionID= id;
            public  String getSectionID(){
                return strSectionID;
            public  void setRubricName(String name){
                this.strRubricName = name;
            public  String getRubricName(){
                return strRubricName;
            public  void setAuthorName(String name){
                this.AuthorName = name;
            public  String getAuthorName(){
                return AuthorName;
            public  void setAuthorAbbrivation(String a){
                this.abbr = a;
            public  String getAuthorAbbrivation(){
                return abbr;
            public void setRubLevel(int rubLevel) {
                this.rubLevel = rubLevel;
            public int getRubLevel() {
                return rubLevel;
            public void setCrossRef(String strCrossRef) {
                this.strCrossRef = strCrossRef;
            public String getCrossRef() {
                return strCrossRef ;
            public void setRemedyList(List remedyList) {
                this.remedyList = remedyList;
            public List getRemedyList() {
                return remedyList;
            public void setAuthor(String Author) {
                this.Author = Author;
            public String getAuthor() {
                return Author;
            public void setChildren(List list) {
                this.children = list;
            public List getChildren() {
                return children;
            public void setOrder(int o){
                this.order = o;
            public int getOrder(){
                return order;
            public void setNumberOfRemedies(int no)
                this.noRem = no;
            public int getNumberOfRemedies()
                return noRem;
            public String toString() {
                String value="";
                value=strRubricName+ " ("+abbr+")";
                return value;
            public Object clone(){
                Test rubric = new Test();
                rubric.Author = Author;
                rubric.children = children;
                rubric.order = order;
                rubric.parent = parent;
                rubric.remedyList = remedyList;
                rubric.rubLevel = rubLevel;
                rubric.strCrossRef = strCrossRef;
                rubric.strParentID = strParentID;
                rubric.strRubricID = strRubricID;
                rubric.strRubricName = strRubricName;
                rubric.strSectionID = strSectionID;
                return rubric;
         @Override
         public TreeNode getChildAt(int paramInt) {
              if (this.children == null) {
                   throw new ArrayIndexOutOfBoundsException("node has no children");
              final TreeNode node = (TreeNode) children.get(paramInt);
              return node;
         @Override
         public int getChildCount() {
              if (this.children == null) {
                   return 0;
              return children.size();
         @Override
         public int getIndex(TreeNode paramTreeNode) {
              // TODO Auto-generated method stub
              return 0;
         @Override
         public boolean getAllowsChildren() {
              return true;
         @Override
         public boolean isLeaf() {
              return children.isEmpty();
         @Override
         public Enumeration children() {
              if (this.children == null) {
                   return EMPTY_ENUMERATION;
              Vector v = new Vector(this.children);
              return v.elements();
         @Override
         public void insert(MutableTreeNode newChild, int paramInt) {
              if (newChild == null) {
                   throw new IllegalArgumentException("new child is null");
              MutableTreeNode oldParent = (MutableTreeNode) newChild.getParent();
              if (oldParent != null) {
                   oldParent.remove(newChild);
              newChild.setParent(this);
              if (children == null) {
                   children = new ArrayList();
              children.add(paramInt, newChild);
         @Override
         public void remove(int childIndex) {
              MutableTreeNode child = (MutableTreeNode) getChildAt(childIndex);
              children.remove(childIndex);
              child.setParent(null);
         @Override
         public void remove(MutableTreeNode aChild) {
              if (aChild == null) {
                   throw new IllegalArgumentException("argument is null");
              if (!isNodeChild(aChild)) {
                   throw new IllegalArgumentException("argument is not a child");
              remove(getIndex(aChild)); // linear search
         public boolean isNodeChild(TreeNode aNode) {
              boolean retval;
              if (aNode == null) {
                   retval = false;
              } else {
                   if (getChildCount() == 0) {
                        retval = false;
                   } else {
                        retval = (aNode.getParent() == this);
              return retval;
         @Override
         public void setUserObject(Object paramObject) {
              // TODO Auto-generated method stub
         @Override
         public void removeFromParent() {
              MutableTreeNode parent = (MutableTreeNode) getParent();
              if (parent != null) {
                   parent.remove(this);
         @Override
         public void setParent(MutableTreeNode paramMutableTreeNode) {
              parent = (Test) paramMutableTreeNode;
          * Returns the path from the root, to get to this node. The last element in
          * the path is this node.
          * @return an array of TreeNode objects giving the path, where the first
          *         element in the path is the root and the last element is this
          *         node.
         public TreeNode[] getPath() {
              return getPathToRoot(this, 0);
          * Builds the parents of node up to and including the root node, where the
          * original node is the last element in the returned array. The length of
          * the returned array gives the node's depth in the tree.
          * @param aNode
          *            the TreeNode to get the path for
          * @param depth
          *            an int giving the number of steps already taken towards the
          *            root (on recursive calls), used to size the returned array
          * @return an array of TreeNodes giving the path from the root to the
          *         specified node
         protected TreeNode[] getPathToRoot(TreeNode aNode, int depth) {
              TreeNode[] retNodes;
               * Check for null, in case someone passed in a null node, or they passed
               * in an element that isn't rooted at root.
              if (aNode == null) {
                   if (depth == 0)
                        return null;
                   else
                        retNodes = new TreeNode[depth];
              } else {
                   depth++;
                   retNodes = getPathToRoot(aNode.getParent(), depth);
                   retNodes[retNodes.length - depth] = aNode;
              return retNodes;
        }

    You have an O(N**2) algorithm at the end that is rather ill-considered. It seems to me at first glance that it could be combined int the previous loop.

  • Problem with JTree

    Hi All,
    Can anyone please help me in writing a method which will take a JTree/TreeNode/MutableTreeNode and a string as parameters, and then search the JTree/TreeNode/MutableTreeNode for that particular string (which will be the name of a node/leaf in the tree), and then expand the JTree to show the node/leaf?
    Thanx a lot in advance,
    Best Regards,
    Debopam.

    Here's something:import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    public class Test extends JFrame {
        private TreePanel treePanel;
        public Test () {
            getContentPane ().setLayout (new BorderLayout ());
            getContentPane ().add (treePanel = new TreePanel ());
            getContentPane ().add (new SearchPanel (), BorderLayout.SOUTH);
            pack ();
            setDefaultCloseOperation (EXIT_ON_CLOSE);
            setLocationRelativeTo (null);
            setTitle ("Test");
            setVisible (true);
        public Dimension getPreferredSize () {
            return new Dimension (600, 600);
        private class TreePanel extends JPanel {
            private DefaultTreeModel model;
            private JTree tree;
            public TreePanel () {
                model = new DefaultTreeModel (createRoot ());
                tree = new JTree (model);
                tree.setRootVisible (false);
                tree.setShowsRootHandles (true);
                setLayout (new BorderLayout ());
                add (new JScrollPane (tree));
            private TreeNode createRoot () {
                DefaultMutableTreeNode root = new DefaultMutableTreeNode ("");
                add (root, 1, 3);
                return root;
            private void add (DefaultMutableTreeNode node, int i, int n) {
                for (int l = 0; l < 26; l ++) {
                    DefaultMutableTreeNode child = new DefaultMutableTreeNode (((String) node.getUserObject ()) + (char) ('a' + l));
                    if (i < n) {
                        add (child, i + 1, n);
                    node.add (child);
            public void searchAndExpand (String text) {
                TreeNode[] path = search ((DefaultMutableTreeNode) model.getRoot (), text);
                if (path != null) {
                    TreePath treePath = new TreePath (path);
                    tree.scrollPathToVisible (treePath);
                    tree.setSelectionPath (treePath);
            private TreeNode[] search (DefaultMutableTreeNode node, Object object) {
                TreeNode[] path = null;
                if (node.getUserObject ().equals (object)) {
                    path = model.getPathToRoot (node);
                } else {
                    int i = 0;
                    int n = model.getChildCount (node);
                    while ((i < n) && (path == null)) {
                        path = search ((DefaultMutableTreeNode) model.getChild (node, i), object);
                        i ++;
                return path;
        private class SearchPanel extends JPanel {
            public SearchPanel () {
                JTextField searchField = new JTextField (10);
                searchField.addActionListener (new ActionListener () {
                    public void actionPerformed (ActionEvent event) {
                        treePanel.searchAndExpand (((JTextField) event.getSource ()).getText ());
                setLayout (new GridBagLayout ());
                add (searchField, new GridBagConstraints ());
        public static void main (String[] parameters) {
            new Test ();
    }Kind regards,
      Levi

  • Problem with JPopupMenu and JTree

    Hi,
    Is there any way to have different JPopupMenu for every node.
    When I right click on the treenode there is popup menu have a "*JCheckBoxMenuItem*". By default the value of that checkbox is false. Now when i try to right click on a particular node and select the checkbox the selected value gets applied to rest of all nodes also.
    How can i just set the value of the checkbox to one perticular node.
    my code is
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    public class TreePopupMenuTest {
      public JComponent makeUI() {
        JTree tree = new JTree();
        tree.setComponentPopupMenu(new TreePopupMenu());
        JPanel p = new JPanel(new BorderLayout());
        p.add(new JScrollPane(tree));
        p.setPreferredSize(new Dimension(320, 240));
        return p;
      class TreePopupMenu extends JPopupMenu {
        private TreePath path;
        private JCheckBoxMenuItem compress=new JCheckBoxMenuItem("Compress");
        public TreePopupMenu() {
          super();
          add(compress);
          compress.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent ie) {
                            if(compress.getState()){
                                 compress.setState(true);
                                    System.out.println("compress clicked");
                            else{
                                 compress.setState(false);
                                    System.out.println("uncompress");
        public void show(Component c, int x, int y) {
          JTree tree = (JTree)c;
          path = tree.getPathForLocation(x, y);
          if(path!=null && path==tree.getAnchorSelectionPath()) {
            super.show(c, x, y);
      public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
          public void run() { createAndShowGUI(); }
      public static void createAndShowGUI() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.getContentPane().add(new TreePopupMenuTest().makeUI());
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }Please help me as soon as possible.
    Thanks.
    Edited by: Kavita_S on Apr 23, 2009 11:49 PM

    Hi,
    Do you know this link?
    [How to Use Trees|http://java.sun.com/docs/books/tutorial/uiswing/components/tree.html]
    Please help me as soon as possible.Sorry that I'm not good at English, I don't understand what you mean.
    Anyway, here's a quick example:
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    public class TreePopupMenuTest3 {
      public JComponent makeUI() {
        JTree tree = new JTree();
        tree.setComponentPopupMenu(new TreePopupMenu());
        JPanel p = new JPanel(new BorderLayout());
        p.add(new JScrollPane(tree));
        p.setPreferredSize(new Dimension(320, 240));
        return p;
      class TreePopupMenu extends JPopupMenu {
        private TreePath path;
        private JCheckBoxMenuItem compress = new JCheckBoxMenuItem("Compress");
        public TreePopupMenu() {
          super();
          add(compress);
          compress.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ie) {
              if (compress.getState()) {
                System.out.println("compress clicked");
                setSelectedPath(path, true);
              } else {
                System.out.println("uncompress");
                setSelectedPath(path, false);
        public void show(Component c, int x, int y) {
          JTree tree = (JTree)c;
          path = tree.getPathForLocation(x, y);
          if (path!=null && path==tree.getAnchorSelectionPath()) {
            compress.setState(isSelectedPath(path));
            super.show(c, x, y);
      class MyData {
        public boolean flag;
        public String name;
        public MyData(String name, boolean flag) {
          this.name = name;
          this.flag = flag;
        @Override public String toString() {
          return name;
      //private Set<TreePath> selectedPath = new HashSet<TreePath>();
      private void setSelectedPath(TreePath p, boolean flag) {
        //if (flag) selectedPath.add(p);
        //else    selectedPath.remove(p);
        DefaultMutableTreeNode node =
              (DefaultMutableTreeNode)p.getLastPathComponent();
        Object o = node.getUserObject();
        if (o instanceof MyData) {
          ((MyData)o).flag = flag;
        } else {
          node.setUserObject(new MyData(o.toString(), flag));
      private boolean isSelectedPath(TreePath p) {
        //return selectedPath.contains(p);
        Object o =
              ((DefaultMutableTreeNode)p.getLastPathComponent()).getUserObject();
        return (o instanceof MyData)?((MyData)o).flag:false;
      public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
          public void run() {
            createAndShowGUI();
      public static void createAndShowGUI() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.getContentPane().add(new TreePopupMenuTest3().makeUI());
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

  • About to use my tree for firewood

    I was wondering if someone could maybe clue me into a problem that I am having with my DefaultMutableTree. See, I call a recursive method to get the file system of the computer, which is what is added to the tree. So the user is looking at a tree structure of the file system of their computer. My problem is that when I compile and run my program the tree shows up fine, with no hitches. I have given my code to other friends, and for some of them it does not show up, and throws a null pointer exception at the internal interface of this recursive method. I was wondering what might be causing this? My friends that have problems with the code are running either WIN XP, or Mac OS 10.1.4. Here is the code for the initialization of the tree (This will look ugly on the post, so I would hope that you would take the time to copy and paste this into your editor :D)
    //code start.
    import java.io.*;
    import java.io.File;
    import java.lang.*;
    import java.util.*;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.event.*;
    import java.beans.*;
    import javax.swing.JTree;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.event.TreeSelectionListener;
    import javax.swing.event.TreeSelectionEvent;
    import javax.swing.tree.TreeSelectionModel;
    public class File_Encryptor extends JFrame {
    private JFrame thisFrame = this;
              private JTree tree;
    private JMenuBar jMenuBar1 = new JMenuBar();
              private JMenuItem menuOpen = new JMenuItem("Open");
              private JMenuItem menuSave = new JMenuItem("Save");
              private JMenuItem menuClose = new JMenuItem("Close");
              private JMenuItem menuQuit = new JMenuItem("Quit");
              private JMenuItem menuAbout = new JMenuItem("About this software...");
              private JMenuItem menuAdd = new JMenuItem("Add key and user");
              private JMenuItem menuChange = new JMenuItem("Change buddy key");
              private JMenuItem menuSend = new JMenuItem("Send your buddy key");
              private JMenuItem menuDelete = new JMenuItem("Delete selected buddy key");
              private JMenuItem menuReset = new JMenuItem("Reset your key");
              private JMenuItem menuChangeLogin = new JMenuItem("Change Login");
              private JMenuItem menuHelp = new JMenuItem("Help...");
              private JButton openDir = new JButton("Open path");
              private JTextField jTextField1 = new JTextField();
              private JScrollPane treeView;
              private JScrollPane imageView;
              private JScrollPane textView;
              private String ROOT;
              private File root;
              private DefaultMutableTreeNode top;
              final private DefaultMutableTreeNode FILLER = new DefaultMutableTreeNode(new FileInfo ("about:blank", "about:blank"));
         public File_Encryptor() throws FileNotFoundException, InterruptedException, IOException, ClassNotFoundException {
    super("FILE ENCRYPTOR 1.0");
                   addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
                        System.exit(0);
                   ROOT = getRoot(System.getProperty("user.home"));
                   root = new File(ROOT);                    
                   try{
                   //Create the nodes.
                   top = unfold(root);
                   top.setUserObject(new FileInfo(ROOT,ROOT));
                   tree = new JTree(top);
                   tree.getSelectionModel().setSelectionMode
    (TreeSelectionModel.SINGLE_TREE_SELECTION);
                   Object nodage = top.getNextNode().getUserObject();
                   FileInfo leaf = (FileInfo) nodage;
                   tree.addTreeSelectionListener(new TreeSelectionListener() {
    public void valueChanged(TreeSelectionEvent e) {
    DefaultMutableTreeNode node = (DefaultMutableTreeNode)
    tree.getLastSelectedPathComponent();
    if (node == null) return;
              try{
                        Object nodeInfo = node.getUserObject();
                        FileInfo temp = (FileInfo) nodeInfo;
                        if((node.isLeaf()) && (!(node.isRoot())))
                             System.out.println(temp.Path());
                             //figure out how to place file in editor pane.
                        else
                             return;
                   catch(Exception fubar)
                        fubar.printStackTrace();
                   treeView = new JScrollPane(tree);
                   treeView.setSize(150,450);
                   jTextField1.setMaximumSize(new Dimension(50, 100));
                   jTextField1.setText("PATH");
                   this.getContentPane().add(jTextField1, BorderLayout.EAST);
                   this.getContentPane().add(treeView, BorderLayout.WEST);
    catch(Exception e) {
    e.printStackTrace();
                   jMenuBar1.setBorder(BorderFactory.createEtchedBorder());
                   JMenu menu = new JMenu("File");
                   JMenu about = new JMenu("Help");
                   JMenu keys = new JMenu("Keys");
                   JMenu change = new JMenu("Login");
                   menuQuit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.META_MASK));
                   menuQuit.setEnabled(true);
                   menuQuit.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                             System.exit(0);
                   menu.add(menuQuit);
                   jMenuBar1.add(menu);
                   jMenuBar1.add(keys);
                   jMenuBar1.add(change);
                   jMenuBar1.add(about);
                   this.setJMenuBar(jMenuBar1);
              public class FileInfo {
              private String path = "";
              private String name = "";
              public FileInfo(String p , String n){
                   path = p;
                   name = n;
              public String toString(){
                   return name;
              public String Path(){
                   return path;
              public static String getFileEx(String po){
              String ext = "";
              int i = po.lastIndexOf('.');
              if(i > 0)
                   ext = po.substring(i-1);
              else
                   ext = null;
              return ext;
              private DefaultMutableTreeNode unfold(File path) {
                   DefaultMutableTreeNode node = new DefaultMutableTreeNode("");
                   Vector Files = new Vector();
                   Vector Direc = new Vector();
                   if((path.isDirectory()) && (path.list().length != 0))
                        node = new DefaultMutableTreeNode(new FileInfo(path.getPath(),path.getName()));
                        File [] childs = path.listFiles();
                        for(int j = 0; j < childs.length; j++)
                             if(childs[j].isDirectory())
                                  Direc.addElement(childs[j]);
                             else
                                  Files.addElement(childs[j]);
                        for(int g = 0; g < Files.size(); g++)
                             Direc.addElement((File)Files.elementAt(g));
                        for(int i = 0; i < Direc.size(); i++)
                             node.add(unfold((File)Direc.elementAt(i)));
                   else if(!(path.isDirectory()))
                        node = new DefaultMutableTreeNode(new FileInfo(path.getPath(),path.getName()));
                   else
                        node = new DefaultMutableTreeNode(new FileInfo(path.getPath(),path.getName()));
                        node.add(new DefaultMutableTreeNode(new FileInfo(null,"<EMPTY FOLDER>")));
                   return node;
              public static String getRoot(String path)
                   int find = path.indexOf(System.getProperty("file.separator"));
                   String root = path.substring(0,find + 1);
                   return root;
    public static void main( String [ ] args )throws FileNotFoundException, InterruptedException, IOException, ClassNotFoundException {
    File_Encryptor show = new File_Encryptor();
    show.setSize(700, 500);
    show.setResizable(false);
    //show.setLocation(100,100);
    show.setVisible(true);
    //code end.
    //well there it is. Hope someone can help me with my problem.
    //I know this code is ugly, but I was trying a bunch of different
    //things hoping something would work. but ehh no such luck.
    //I am running windows 98, yea that's prolly my problem.
    //thank you for your time.

    This will make the code less ugly.
    > //code start.
    import java.io.*;
    import java.io.File;
    import java.lang.*;
    import java.util.*;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.event.*;
    import java.beans.*;
    import javax.swing.JTree;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.event.TreeSelectionListener;
    import javax.swing.event.TreeSelectionEvent;
    import javax.swing.tree.TreeSelectionModel;
    public class File_Encryptor extends JFrame {
    private JFrame thisFrame = this;
              private JTree tree;
    private JMenuBar jMenuBar1 = new JMenuBar();
              private JMenuItem menuOpen = new JMenuItem("Open");
              private JMenuItem menuSave = new JMenuItem("Save");
    private JMenuItem menuClose = new
    w JMenuItem("Close");
              private JMenuItem menuQuit = new JMenuItem("Quit");
    private JMenuItem menuAbout = new JMenuItem("About this software...");
    private JMenuItem menuAdd = new JMenuItem("Add key and user");
    private JMenuItem menuChange = new JMenuItem("Change buddy key");
    private JMenuItem menuSend = new JMenuItem("Send your buddy key");
    private JMenuItem menuDelete = new JMenuItem("Delete selected buddy key");
    private JMenuItem menuReset = new JMenuItem("Reset your key");
    private JMenuItem menuChangeLogin = new
    w JMenuItem("Change Login");
    private JMenuItem menuHelp = new
    w JMenuItem("Help...");
              private JButton openDir = new JButton("Open path");
              private JTextField jTextField1 = new JTextField();
              private JScrollPane treeView;
              private JScrollPane imageView;
              private JScrollPane textView;
              private String ROOT;
              private File root;
              private DefaultMutableTreeNode top;
    final private DefaultMutableTreeNode FILLER = new
    w DefaultMutableTreeNode(new FileInfo ("about:blank",
    "about:blank"));
    public File_Encryptor() throws FileNotFoundException,
    InterruptedException, IOException,
    ClassNotFoundException {
    super("FILE ENCRYPTOR 1.0");
                   addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e)
    dowEvent e) {
                        System.exit(0);
                   ROOT = getRoot(System.getProperty("user.home"));
                   root = new File(ROOT);                    
                   try{
                   //Create the nodes.
                   top = unfold(root);
                   top.setUserObject(new FileInfo(ROOT,ROOT));
                   tree = new JTree(top);
                   tree.getSelectionModel().setSelectionMode
    (TreeSelectionModel.SINGLE_TREE_SELECTION);
                   Object nodage = top.getNextNode().getUserObject();
                   FileInfo leaf = (FileInfo) nodage;
    tree.addTreeSelectionListener(new
    ew TreeSelectionListener() {
    public void
    public void valueChanged(TreeSelectionEvent e) {
    DefaultMutableTreeNode node =
    TreeNode node = (DefaultMutableTreeNode)
    tree.getLastSelectedPathComponent();
    if (node == null) return;
              try{
                        Object nodeInfo = node.getUserObject();
                        FileInfo temp = (FileInfo) nodeInfo;
                        if((node.isLeaf()) && (!(node.isRoot())))
                             System.out.println(temp.Path());
                             //figure out how to place file in editor pane.
                        else
                             return;
                   catch(Exception fubar)
                        fubar.printStackTrace();
                   treeView = new JScrollPane(tree);
                   treeView.setSize(150,450);
    jTextField1.setMaximumSize(new Dimension(50,
    0, 100));
                   jTextField1.setText("PATH");
    this.getContentPane().add(jTextField1,
    1, BorderLayout.EAST);
    this.getContentPane().add(treeView,
    w, BorderLayout.WEST);
    catch(Exception e) {
    e.printStackTrace();
                   jMenuBar1.setBorder(BorderFactory.createEtchedBorder
                   JMenu menu = new JMenu("File");
                   JMenu about = new JMenu("Help");
                   JMenu keys = new JMenu("Keys");
                   JMenu change = new JMenu("Login");
                   menuQuit.setAccelerator(KeyStroke.getKeyStroke(KeyEv
    nt.VK_Q, ActionEvent.META_MASK));
                   menuQuit.setEnabled(true);
                   menuQuit.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                             System.exit(0);
                   menu.add(menuQuit);
                   jMenuBar1.add(menu);
                   jMenuBar1.add(keys);
                   jMenuBar1.add(change);
                   jMenuBar1.add(about);
                   this.setJMenuBar(jMenuBar1);
              public class FileInfo {
              private String path = "";
              private String name = "";
              public FileInfo(String p , String n){
                   path = p;
                   name = n;
              public String toString(){
                   return name;
              public String Path(){
                   return path;
              public static String getFileEx(String po){
              String ext = "";
              int i = po.lastIndexOf('.');
              if(i > 0)
                   ext = po.substring(i-1);
              else
                   ext = null;
              return ext;
              private DefaultMutableTreeNode unfold(File path) {
    DefaultMutableTreeNode node = new
    ew DefaultMutableTreeNode("");
                   Vector Files = new Vector();
                   Vector Direc = new Vector();
    if((path.isDirectory()) && (path.list().length !=
    != 0))
    node = new DefaultMutableTreeNode(new
    new FileInfo(path.getPath(),path.getName()));
                        File [] childs = path.listFiles();
                        for(int j = 0; j < childs.length; j++)
                             if(childs[j].isDirectory())
                                  Direc.addElement(childs[j]);
                             else
                                  Files.addElement(childs[j]);
                        for(int g = 0; g < Files.size(); g++)
                             Direc.addElement((File)Files.elementAt(g));
                        for(int i = 0; i < Direc.size(); i++)
                             node.add(unfold((File)Direc.elementAt(i)));
                   else if(!(path.isDirectory()))
    node = new DefaultMutableTreeNode(new
    new FileInfo(path.getPath(),path.getName()));
                   else
    node = new DefaultMutableTreeNode(new
    new FileInfo(path.getPath(),path.getName()));
    node.add(new DefaultMutableTreeNode(new
    new FileInfo(null,"<EMPTY FOLDER>")));
                   return node;
              public static String getRoot(String path)
    int find =
    =
    path.indexOf(System.getProperty("file.separator"));
                   String root = path.substring(0,find + 1);
                   return root;
    public static void main( String [ ] args
    ] args )throws FileNotFoundException,
    InterruptedException, IOException,
    ClassNotFoundException {
    File_Encryptor show = new
    show = new File_Encryptor();
    show.setSize(700, 500);
    show.setResizable(false);
    //show.setLocation(100,100);
    show.setVisible(true);
    //code end.

  • About to use my tree for some firewood  :o(

    I was wondering if someone could maybe clue me into a problem that I am having with my DefaultMutableTree. See, I call a recursive method to get the file system of the computer, which is what is added to the tree. So the user is looking at a tree structure of the file system of their computer. My problem is that when I compile and run my program the tree shows up fine, with no hitches. I have given my code to other friends, and for some of them it does not show up, and throws a null pointer exception at the internal interface of this recursive method. I was wondering what might be causing this? My friends that have problems with the code are running either WIN XP, or Mac OS 10.1.4. Here is the code for the initialization of the tree (This will look ugly on the post, so I would hope that you would take the time to copy and paste this into your editor :D)
    //code start.
    import java.io.*;
    import java.io.File;
    import java.lang.*;
    import java.util.*;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.event.*;
    import java.beans.*;
    import javax.swing.JTree;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.event.TreeSelectionListener;
    import javax.swing.event.TreeSelectionEvent;
    import javax.swing.tree.TreeSelectionModel;
    public class File_Encryptor extends JFrame {
    private JFrame thisFrame = this;
    private JTree tree;
    private JMenuBar jMenuBar1 = new JMenuBar();
    private JMenuItem menuOpen = new JMenuItem("Open");
    private JMenuItem menuSave = new JMenuItem("Save");
    private JMenuItem menuClose = new JMenuItem("Close");
    private JMenuItem menuQuit = new JMenuItem("Quit");
    private JMenuItem menuAbout = new JMenuItem("About this software...");
    private JMenuItem menuAdd = new JMenuItem("Add key and user");
    private JMenuItem menuChange = new JMenuItem("Change buddy key");
    private JMenuItem menuSend = new JMenuItem("Send your buddy key");
    private JMenuItem menuDelete = new JMenuItem("Delete selected buddy key");
    private JMenuItem menuReset = new JMenuItem("Reset your key");
    private JMenuItem menuChangeLogin = new JMenuItem("Change Login");
    private JMenuItem menuHelp = new JMenuItem("Help...");
    private JButton openDir = new JButton("Open path");
    private JTextField jTextField1 = new JTextField();
    private JScrollPane treeView;
    private JScrollPane imageView;
    private JScrollPane textView;
    private String ROOT;
    private File root;
    private DefaultMutableTreeNode top;
    final private DefaultMutableTreeNode FILLER = new DefaultMutableTreeNode(new FileInfo ("about:blank", "about:blank"));
    public File_Encryptor() throws FileNotFoundException, InterruptedException, IOException, ClassNotFoundException {
    super("FILE ENCRYPTOR 1.0");
    addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
    System.exit(0);
    ROOT = getRoot(System.getProperty("user.home"));
    root = new File(ROOT);
    try{
    //Create the nodes.
    top = unfold(root);
    top.setUserObject(new FileInfo(ROOT,ROOT));
    tree = new JTree(top);
    tree.getSelectionModel().setSelectionMode
    (TreeSelectionModel.SINGLE_TREE_SELECTION);
    Object nodage = top.getNextNode().getUserObject();
    FileInfo leaf = (FileInfo) nodage;
    tree.addTreeSelectionListener(new TreeSelectionListener() {
    public void valueChanged(TreeSelectionEvent e) {
    DefaultMutableTreeNode node = (DefaultMutableTreeNode)
    tree.getLastSelectedPathComponent();
    if (node == null) return;
    try{
    Object nodeInfo = node.getUserObject();
    FileInfo temp = (FileInfo) nodeInfo;
    if((node.isLeaf()) && (!(node.isRoot())))
    System.out.println(temp.Path());
    //figure out how to place file in editor pane.
    else
    return;
    catch(Exception fubar)
    fubar.printStackTrace();
    treeView = new JScrollPane(tree);
    treeView.setSize(150,450);
    jTextField1.setMaximumSize(new Dimension(50, 100));
    jTextField1.setText("PATH");
    this.getContentPane().add(jTextField1, BorderLayout.EAST);
    this.getContentPane().add(treeView, BorderLayout.WEST);
    catch(Exception e) {
    e.printStackTrace();
    jMenuBar1.setBorder(BorderFactory.createEtchedBorder());
    JMenu menu = new JMenu("File");
    JMenu about = new JMenu("Help");
    JMenu keys = new JMenu("Keys");
    JMenu change = new JMenu("Login");
    menuQuit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.META_MASK));
    menuQuit.setEnabled(true);
    menuQuit.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    System.exit(0);
    menu.add(menuQuit);
    jMenuBar1.add(menu);
    jMenuBar1.add(keys);
    jMenuBar1.add(change);
    jMenuBar1.add(about);
    this.setJMenuBar(jMenuBar1);
    public class FileInfo {
    private String path = "";
    private String name = "";
    public FileInfo(String p , String n){
    path = p;
    name = n;
    public String toString(){
    return name;
    public String Path(){
    return path;
    public static String getFileEx(String po){
    String ext = "";
    int i = po.lastIndexOf('.');
    if(i > 0)
    ext = po.substring(i-1);
    else
    ext = null;
    return ext;
    private DefaultMutableTreeNode unfold(File path) {
    DefaultMutableTreeNode node = new DefaultMutableTreeNode("");
    Vector Files = new Vector();
    Vector Direc = new Vector();
    if((path.isDirectory()) && (path.list().length != 0))
    node = new DefaultMutableTreeNode(new FileInfo(path.getPath(),path.getName()));
    File [] childs = path.listFiles();
    for(int j = 0; j < childs.length; j++)
    if(childs[j].isDirectory())
    Direc.addElement(childs[j]);
    else
    Files.addElement(childs[j]);
    for(int g = 0; g < Files.size(); g++)
    Direc.addElement((File)Files.elementAt(g));
    for(int i = 0; i < Direc.size(); i++)
    node.add(unfold((File)Direc.elementAt(i)));
    else if(!(path.isDirectory()))
    node = new DefaultMutableTreeNode(new FileInfo(path.getPath(),path.getName()));
    else
    node = new DefaultMutableTreeNode(new FileInfo(path.getPath(),path.getName()));
    node.add(new DefaultMutableTreeNode(new FileInfo(null,"<EMPTY FOLDER>")));
    return node;
    public static String getRoot(String path)
    int find = path.indexOf(System.getProperty("file.separator"));
    String root = path.substring(0,find + 1);
    return root;
    public static void main( String [ ] args )throws FileNotFoundException, InterruptedException, IOException, ClassNotFoundException {
    File_Encryptor show = new File_Encryptor();
    show.setSize(700, 500);
    show.setResizable(false);
    //show.setLocation(100,100);
    show.setVisible(true);
    //code end.
    //well there it is. Hope someone can help me with my problem.
    //I know this code is ugly, but I was trying a bunch of different
    //things hoping something would work. but ehh no such luck.
    //I am running windows 98, yea that's prolly my problem.
    //thank you for your time.

    I ran this on XP and got the null pointer exception...
    it's likely that it's running into a file or directory that it can't list (in my case it was a mount on a different directory ntfs is kinda cool)... SO... to handle that problem I just put the whole method in a try / catch block
    it was just the method unfold ... the fix returns a blank treenode... it should probably return null and the caller should see that as a sign to not add it to the tree...
         private DefaultMutableTreeNode unfold(File path) {
              DefaultMutableTreeNode node = new DefaultMutableTreeNode("");
              try
                   Vector Files = new Vector();
                   Vector Direc = new Vector();
                   if(path==null)
                        return(node);
                   if((path.isDirectory()) && (path.list().length != 0))
                   node = new DefaultMutableTreeNode(new FileInfo(path.getPath(),path.getName()));
                   File [] childs = path.listFiles();
                   for(int j = 0; j < childs.length; j++)
                   if(childs[j].isDirectory())
                   Direc.addElement(childs[j]);
                   else
                   Files.addElement(childs[j]);
                   for(int g = 0; g < Files.size(); g++)
                   Direc.addElement((File)Files.elementAt(g));
                   for(int i = 0; i < Direc.size(); i++)
                   node.add(unfold((File)Direc.elementAt(i)));
                   else if(!(path.isDirectory()))
                   node = new DefaultMutableTreeNode(new FileInfo(path.getPath(),path.getName()));
                   else
                   node = new DefaultMutableTreeNode(new FileInfo(path.getPath(),path.getName()));
                   node.add(new DefaultMutableTreeNode(new FileInfo(null,"<EMPTY FOLDER>")));
              catch (Exception e)
              return node;
         }

  • About to use my friggin tree for firewood  :o(

    I was wondering if someone could maybe clue me into a problem that I am having with my DefaultMutableTree. See, I call a recursive method to get the file system of the computer, which is what is added to the tree. So the user is looking at a tree structure of the file system of their computer. My problem is that when I compile and run my program the tree shows up fine, with no hitches. I have given my code to other friends, and for some of them it does not show up, and throws a null pointer exception at the internal interface of this recursive method. I was wondering what might be causing this? My friends that have problems with the code are running either WIN XP, or Mac OS 10.1.4. Here is the code for the initialization of the tree (This will look ugly on the post, so I would hope that you would take the time to copy and paste this into your editor :D)
    //code start.
    import java.io.*;
    import java.io.File;
    import java.lang.*;
    import java.util.*;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.event.*;
    import java.beans.*;
    import javax.swing.JTree;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.event.TreeSelectionListener;
    import javax.swing.event.TreeSelectionEvent;
    import javax.swing.tree.TreeSelectionModel;
    public class File_Encryptor extends JFrame {
    private JFrame thisFrame = this;
    private JTree tree;
    private JMenuBar jMenuBar1 = new JMenuBar();
    private JMenuItem menuOpen = new JMenuItem("Open");
    private JMenuItem menuSave = new JMenuItem("Save");
    private JMenuItem menuClose = new JMenuItem("Close");
    private JMenuItem menuQuit = new JMenuItem("Quit");
    private JMenuItem menuAbout = new JMenuItem("About this software...");
    private JMenuItem menuAdd = new JMenuItem("Add key and user");
    private JMenuItem menuChange = new JMenuItem("Change buddy key");
    private JMenuItem menuSend = new JMenuItem("Send your buddy key");
    private JMenuItem menuDelete = new JMenuItem("Delete selected buddy key");
    private JMenuItem menuReset = new JMenuItem("Reset your key");
    private JMenuItem menuChangeLogin = new JMenuItem("Change Login");
    private JMenuItem menuHelp = new JMenuItem("Help...");
    private JButton openDir = new JButton("Open path");
    private JTextField jTextField1 = new JTextField();
    private JScrollPane treeView;
    private JScrollPane imageView;
    private JScrollPane textView;
    private String ROOT;
    private File root;
    private DefaultMutableTreeNode top;
    final private DefaultMutableTreeNode FILLER = new DefaultMutableTreeNode(new FileInfo ("about:blank", "about:blank"));
    public File_Encryptor() throws FileNotFoundException, InterruptedException, IOException, ClassNotFoundException {
    super("FILE ENCRYPTOR 1.0");
    addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
    System.exit(0);
    ROOT = getRoot(System.getProperty("user.home"));
    root = new File(ROOT);
    try{
    //Create the nodes.
    top = unfold(root);
    top.setUserObject(new FileInfo(ROOT,ROOT));
    tree = new JTree(top);
    tree.getSelectionModel().setSelectionMode
    (TreeSelectionModel.SINGLE_TREE_SELECTION);
    Object nodage = top.getNextNode().getUserObject();
    FileInfo leaf = (FileInfo) nodage;
    tree.addTreeSelectionListener(new TreeSelectionListener() {
    public void valueChanged(TreeSelectionEvent e) {
    DefaultMutableTreeNode node = (DefaultMutableTreeNode)
    tree.getLastSelectedPathComponent();
    if (node == null) return;
    try{
    Object nodeInfo = node.getUserObject();
    FileInfo temp = (FileInfo) nodeInfo;
    if((node.isLeaf()) && (!(node.isRoot())))
    System.out.println(temp.Path());
    //figure out how to place file in editor pane.
    else
    return;
    catch(Exception fubar)
    fubar.printStackTrace();
    treeView = new JScrollPane(tree);
    treeView.setSize(150,450);
    jTextField1.setMaximumSize(new Dimension(50, 100));
    jTextField1.setText("PATH");
    this.getContentPane().add(jTextField1, BorderLayout.EAST);
    this.getContentPane().add(treeView, BorderLayout.WEST);
    catch(Exception e) {
    e.printStackTrace();
    jMenuBar1.setBorder(BorderFactory.createEtchedBorder());
    JMenu menu = new JMenu("File");
    JMenu about = new JMenu("Help");
    JMenu keys = new JMenu("Keys");
    JMenu change = new JMenu("Login");
    menuQuit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.META_MASK));
    menuQuit.setEnabled(true);
    menuQuit.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    System.exit(0);
    menu.add(menuQuit);
    jMenuBar1.add(menu);
    jMenuBar1.add(keys);
    jMenuBar1.add(change);
    jMenuBar1.add(about);
    this.setJMenuBar(jMenuBar1);
    public class FileInfo {
    private String path = "";
    private String name = "";
    public FileInfo(String p , String n){
    path = p;
    name = n;
    public String toString(){
    return name;
    public String Path(){
    return path;
    public static String getFileEx(String po){
    String ext = "";
    int i = po.lastIndexOf('.');
    if(i > 0)
    ext = po.substring(i-1);
    else
    ext = null;
    return ext;
    private DefaultMutableTreeNode unfold(File path) {
    DefaultMutableTreeNode node = new DefaultMutableTreeNode("");
    Vector Files = new Vector();
    Vector Direc = new Vector();
    if((path.isDirectory()) && (path.list().length != 0))
    node = new DefaultMutableTreeNode(new FileInfo(path.getPath(),path.getName()));
    File [] childs = path.listFiles();
    for(int j = 0; j < childs.length; j++)
    if(childs[j].isDirectory())
    Direc.addElement(childs[j]);
    else
    Files.addElement(childs[j]);
    for(int g = 0; g < Files.size(); g++)
    Direc.addElement((File)Files.elementAt(g));
    for(int i = 0; i < Direc.size(); i++)
    node.add(unfold((File)Direc.elementAt(i)));
    else if(!(path.isDirectory()))
    node = new DefaultMutableTreeNode(new FileInfo(path.getPath(),path.getName()));
    else
    node = new DefaultMutableTreeNode(new FileInfo(path.getPath(),path.getName()));
    node.add(new DefaultMutableTreeNode(new FileInfo(null,"<EMPTY FOLDER>")));
    return node;
    public static String getRoot(String path)
    int find = path.indexOf(System.getProperty("file.separator"));
    String root = path.substring(0,find + 1);
    return root;
    public static void main( String [ ] args )throws FileNotFoundException, InterruptedException, IOException, ClassNotFoundException {
    File_Encryptor show = new File_Encryptor();
    show.setSize(700, 500);
    show.setResizable(false);
    //show.setLocation(100,100);
    show.setVisible(true);
    //code end.
    //well there it is. Hope someone can help me with my problem.
    //I know this code is ugly, but I was trying a bunch of different
    //things hoping something would work. but ehh no such luck.
    //I am running windows 98, yea that's prolly my problem.
    //thank you for your time.

    So you consider this exact post appropriate for both the Advanced Language Topics and New to Java Technology? Did you post this question anywhere else? Don't double post.
    Anyway, check the post in NtJT. The answer is there.

  • JTree custom renderer setting selection background color problem

    Hi,
    I have a JTree with a custom icon renderer that displays an icon. The JTree is part of a TreeTable component. Iam having a problem setting the selection background uniformly for the entire row. There is no problem when there is no row selected in the JTable.
    My present code looks like this:
    Iam overriding paint in my renderer which extends DefaultCellRenderer.
           super.paint(g);
            Color bColor = null;
            if(!m_selected) {
                 if(currRow % 2 == 0) {
                      bColor = Color.WHITE;
                 } else {
                                                    bColor = backColor;
            } else {
                 bColor = table.getSelectionBackground();                  bColor = getRowSelectionColor();
         if(bColor != null) {
                           g.setColor(bColor);
             if(!m_selected) {
                   g.setXORMode(new Color(0xFF, 0xFF, 0xFF));
             } else {
                 g.setXORMode(new Color(0x00, 0x00, 0x00));
                  I have a color I arrive at using some algorithm that I want using method getRowSelectionColor(). The other cells in the row have this color. But the cell containing the tree node shows different color. Iam not able to arrive at the right combination of the color to set and the xor color so my tree node also looks like the other cells in the row.
    It is not a problem really as the table still looks good. Its just that the tree node looks like it has been highlighted and this might cause a problem when a table cell is highlighed later on in the application ( two cells in the row would be highlighted causing confusion).
    Any help would be appreciated.
    Regards,
    vidyut

    Hi Camickr,
    Thanks for the reply. Iam sorry I didn't include the sources the first time around. There were too many of them. I have created a small, self-contained, compilable program that demonstrates the problem and including it herewith. Still there's quite many files but they are all needed Iam afraid. The only one you will have to concern yourself fior this problem is the file IconRenderer.java. The treenode background and the other cells background are not in sync when table row is not selected in this example though. But they are in my real program. I just need them to be in sync i.e have the same background color when the row is selected.
    Your help would be very much appreciated.
    These are the files that are included below:
    1. AbstractTreeTableModel.java
    2. Bookmarks.java
    3. BookmarksModel.java
    4. DynamicTreeTableModel.java
    5. IconRenderer.java
    6. IndicatorRenderer.java
    7. JTreeTable.java
    8. TreeTableExample3.java (contains main)
    9. TreeTableModel.java
    10. TreeTableModelAdapter.java
    The copyright and javadocs information has been stripped for clarity.
    cheers,
    vidyut
    // AbstractTreeTableModel.java BEGIN
    import javax.swing.tree.*;
    import javax.swing.event.*;
    public abstract class AbstractTreeTableModel implements TreeTableModel {
        protected Object root;    
        protected EventListenerList listenerList = new EventListenerList();
        public AbstractTreeTableModel(Object root) {
            this.root = root;
        // Default implementations for methods in the TreeModel interface.
        public Object getRoot() {
            return root;
        public boolean isLeaf(Object node) {
            return getChildCount(node) == 0;
        public void valueForPathChanged(TreePath path, Object newValue) {}
        // This is not called in the JTree's default mode:
        // use a naive implementation.
        public int getIndexOfChild(Object parent, Object child) {
            for (int i = 0; i < getChildCount(parent); i++) {
             if (getChild(parent, i).equals(child)) {
                 return i;
         return -1;
        public void addTreeModelListener(TreeModelListener l) {
            listenerList.add(TreeModelListener.class, l);
        public void removeTreeModelListener(TreeModelListener l) {
            listenerList.remove(TreeModelListener.class, l);
        protected void fireTreeNodesChanged(Object source, Object[] path,
                                            int[] childIndices,
                                            Object[] children) {
            // Guaranteed to return a non-null array
            Object[] listeners = listenerList.getListenerList();
            TreeModelEvent e = null;
            // Process the listeners last to first, notifying
            // those that are interested in this event
            for (int i = listeners.length-2; i>=0; i-=2) {
                if (listeners==TreeModelListener.class) {
    // Lazily create the event:
    if (e == null)
    e = new TreeModelEvent(source, path,
    childIndices, children);
    ((TreeModelListener)listeners[i+1]).treeNodesChanged(e);
    protected void fireTreeNodesInserted(Object source, Object[] path,
    int[] childIndices,
    Object[] children) {
    // Guaranteed to return a non-null array
    Object[] listeners = listenerList.getListenerList();
    TreeModelEvent e = null;
    // Process the listeners last to first, notifying
    // those that are interested in this event
    for (int i = listeners.length-2; i>=0; i-=2) {
    if (listeners[i]==TreeModelListener.class) {
    // Lazily create the event:
    if (e == null)
    e = new TreeModelEvent(source, path,
    childIndices, children);
    ((TreeModelListener)listeners[i+1]).treeNodesInserted(e);
    protected void fireTreeNodesRemoved(Object source, Object[] path,
    int[] childIndices,
    Object[] children) {
    // Guaranteed to return a non-null array
    Object[] listeners = listenerList.getListenerList();
    TreeModelEvent e = null;
    // Process the listeners last to first, notifying
    // those that are interested in this event
    for (int i = listeners.length-2; i>=0; i-=2) {
    if (listeners[i]==TreeModelListener.class) {
    // Lazily create the event:
    if (e == null)
    e = new TreeModelEvent(source, path,
    childIndices, children);
    ((TreeModelListener)listeners[i+1]).treeNodesRemoved(e);
    protected void fireTreeStructureChanged(Object source, Object[] path,
    int[] childIndices,
    Object[] children) {
    // Guaranteed to return a non-null array
    Object[] listeners = listenerList.getListenerList();
    TreeModelEvent e = null;
    // Process the listeners last to first, notifying
    // those that are interested in this event
    for (int i = listeners.length-2; i>=0; i-=2) {
    if (listeners[i]==TreeModelListener.class) {
    // Lazily create the event:
    if (e == null)
    e = new TreeModelEvent(source, path,
    childIndices, children);
    ((TreeModelListener)listeners[i+1]).treeStructureChanged(e);
    // Default impelmentations for methods in the TreeTableModel interface.
    public Class getColumnClass(int column) { return Object.class; }
    public boolean isCellEditable(Object node, int column) {
    return getColumnClass(column) == TreeTableModel.class;
    public void setValueAt(Object aValue, Object node, int column) {}
    // Left to be implemented in the subclass:
    * public Object getChild(Object parent, int index)
    * public int getChildCount(Object parent)
    * public int getColumnCount()
    * public String getColumnName(Object node, int column)
    * public Object getValueAt(Object node, int column)
    // AbstractTreeTableModel.java END
    // Bookmarks.java BEGIN
    import java.io.*;
    import java.net.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    import javax.swing.text.*;
    import javax.swing.text.html.*;
    import javax.swing.text.html.parser.*;
    public class Bookmarks {
    /** The root node the bookmarks are added to. */
    private BookmarkDirectory root;
    * Creates a new Bookmarks object, with the entries coming from
    * <code>path</code>.
    public Bookmarks(String path) {
         root = new BookmarkDirectory("Bookmarks");
         if (path != null) {
         parse(path);
    * Returns the root of the bookmarks.
    public BookmarkDirectory getRoot() {
         return root;
    protected void parse(String path) {
         try {
         BufferedReader reader = new BufferedReader(new FileReader
                                       (path));
         new ParserDelegator().parse(reader, new CallbackHandler(), true);
         catch (IOException ioe) {
         System.out.println("IOE: " + ioe);
         JOptionPane.showMessageDialog(null, "Load Bookmarks",
                             "Unable to load bookmarks",
                             JOptionPane.ERROR_MESSAGE);
    private static final short NO_ENTRY = 0;
    private static final short BOOKMARK_ENTRY = 2;
    private static final short DIRECTORY_ENTRY = 3;
    private class CallbackHandler extends HTMLEditorKit.ParserCallback {
         /** Parent node that new entries are added to. */
         private BookmarkDirectory parent;
         /** The most recently parsed tag. */
         private HTML.Tag tag;
         /** The last tag encountered. */
         private HTML.Tag lastTag;
         * The state, will be one of NO_ENTRY, DIRECTORY_ENTRY,
    * or BOOKMARK_ENTRY.
         private short state;
         * Date for the next BookmarkDirectory node.
         private Date parentDate;
         * The values from the attributes are placed in here. When the
         * text is encountered this is added to the node hierarchy and a
    * new instance is created.
         private BookmarkEntry lastBookmark;
         * Creates the CallbackHandler.
         public CallbackHandler() {
         parent = root;
         lastBookmark = new BookmarkEntry();
         // HTMLEditorKit.ParserCallback methods
         * Invoked when text in the html document is encountered. Based on
         * the current state, this will either: do nothing
    * (state == NO_ENTRY),
         * create a new BookmarkEntry (state == BOOKMARK_ENTRY) or
    * create a new
         * BookmarkDirectory (state == DIRECTORY_ENTRY). If state is
    * != NO_ENTRY, it is reset to NO_ENTRY after this is
    * invoked.
    public void handleText(char[] data, int pos) {
         switch (state) {
         case NO_ENTRY:
              break;
         case BOOKMARK_ENTRY:
              // URL.
              lastBookmark.setName(new String(data));
    parent.add(lastBookmark);
    lastBookmark = new BookmarkEntry();
              break;
         case DIRECTORY_ENTRY:
              // directory.
              BookmarkDirectory newParent = new
                   BookmarkDirectory(new String(data));
              newParent.setCreated(parentDate);
              parent.add(newParent);
              parent = newParent;
              break;
         default:
              break;
    state = NO_ENTRY;
         * Invoked when a start tag is encountered. Based on the tag
         * this may update the BookmarkEntry and state, or update the
         * parentDate.
         public void handleStartTag(HTML.Tag t, MutableAttributeSet a,
                        int pos) {
         lastTag = tag;
         tag = t;
         if (t == HTML.Tag.A && lastTag == HTML.Tag.DT) {
    long lDate;
              // URL
              URL url;
              try {
              url = new URL((String)a.getAttribute(HTML.Attribute.HREF));
              } catch (MalformedURLException murle) {
              url = null;
              lastBookmark.setLocation(url);
              // created
              Date date;
              try {
    lDate = Long.parseLong((String)a.getAttribute("add_date"));
    if (lDate != 0l) {
    date = new Date(1000l * lDate);
    else {
    date = null;
              } catch (Exception ex) {
              date = null;
              lastBookmark.setCreated(date);
              // last visited
              try {
    lDate = Long.parseLong((String)a.
    getAttribute("last_visit"));
    if (lDate != 0l) {
    date = new Date(1000l * lDate);
    else {
    date = null;
              } catch (Exception ex) {
              date = null;
              lastBookmark.setLastVisited(date);
              state = BOOKMARK_ENTRY;
         else if (t == HTML.Tag.H3 && lastTag == HTML.Tag.DT) {
              // new node.
              try {
              parentDate = new Date(1000l * Long.parseLong((String)a.
                                  getAttribute("add_date")));
              } catch (Exception ex) {
              parentDate = null;
              state = DIRECTORY_ENTRY;
         * Invoked when the end of a tag is encountered. If the tag is
         * a DL, this will set the node that parents are added to the current
         * nodes parent.
         public void handleEndTag(HTML.Tag t, int pos) {
         if (t == HTML.Tag.DL && parent != null) {
              parent = (BookmarkDirectory)parent.getParent();
    public static class BookmarkDirectory extends DefaultMutableTreeNode {
         /** Dates created. */
         private Date created;
         public BookmarkDirectory(String name) {
         super(name);
         public void setName(String name) {
         setUserObject(name);
         public String getName() {
         return (String)getUserObject();
         public void setCreated(Date date) {
         this.created = date;
         public Date getCreated() {
         return created;
    public static class BookmarkEntry extends DefaultMutableTreeNode {
         /** User description of the string. */
         private String name;
         /** The URL the bookmark represents. */
         private URL location;
         /** Dates the URL was last visited. */
         private Date lastVisited;
         /** Date the URL was created. */
         private Date created;
         public void setName(String name) {
         this.name = name;
         public String getName() {
         return name;
         public void setLocation(URL location) {
         this.location = location;
         public URL getLocation() {
         return location;
         public void setLastVisited(Date date) {
         lastVisited = date;
         public Date getLastVisited() {
         return lastVisited;
         public void setCreated(Date date) {
         this.created = date;
         public Date getCreated() {
         return created;
         public String toString() {
         return getName();
    // Bookmarks.java END
    // BookmarksModel.java BEGIN
    import java.util.Date;
    public class BookmarksModel extends DynamicTreeTableModel {
    * Names of the columns.
    private static final String[] columnNames =
    { "Name", "Location", "Last Visited", "Created" };
    * Method names used to access the data to display.
    private static final String[] methodNames =
    { "getName", "getLocation", "getLastVisited","getCreated" };
    * Method names used to set the data.
    private static final String[] setterMethodNames =
    { "setName", "setLocation", "setLastVisited","setCreated" };
    private static final Class[] classes =
    { TreeTableModel.class, String.class, Date.class, Date.class };
    public BookmarksModel(Bookmarks.BookmarkDirectory root) {
         super(root, columnNames, methodNames, setterMethodNames, classes);
    public boolean isCellEditable(Object node, int column) {
         switch (column) {
         case 0:
         // Allow editing of the name, as long as not the root.
         return (node != getRoot());
         case 1:
         // Allow editing of the location, as long as not a
         // directory
         return (node instanceof Bookmarks.BookmarkEntry);
         default:
         // Don't allow editing of the date fields.
         return false;
    // BookmarksModel.java END
    // DynamicTreeTableModel.java BEGIN
    import java.lang.reflect.*;
    import javax.swing.tree.*;
    public class DynamicTreeTableModel extends AbstractTreeTableModel {
    /** Names of the columns, used for the TableModel getColumnName method. */
    private String[] columnNames;
    private String[] methodNames;
    private String[] setterMethodNames;
    /** Column classes, used for the TableModel method getColumnClass. */
    private Class[] cTypes;
    public DynamicTreeTableModel(TreeNode root, String[] columnNames,
                        String[] getterMethodNames,
                        String[] setterMethodNames,
                        Class[] cTypes) {
         super(root);
         this.columnNames = columnNames;
         this.methodNames = getterMethodNames;
         this.setterMethodNames = setterMethodNames;
         this.cTypes = cTypes;
    public int getChildCount(Object node) {
         return ((TreeNode)node).getChildCount();
    public Object getChild(Object node, int i) {
         return ((TreeNode)node).getChildAt(i);
    public boolean isLeaf(Object node) {
         return ((TreeNode)node).isLeaf();
    public int getColumnCount() {
         return columnNames.length;
    public String getColumnName(int column) {
         if (cTypes == null || column < 0 || column >= cTypes.length) {
         return null;
         return columnNames[column];
    public Class getColumnClass(int column) {
         if (cTypes == null || column < 0 || column >= cTypes.length) {
         return null;
         return cTypes[column];
    public Object getValueAt(Object node, int column) {
         try {
         Method method = node.getClass().getMethod(methodNames[column],
                                  null);
         if (method != null) {
              return method.invoke(node, null);
         catch (Throwable th) {}
         return null;
    * Returns true if there is a setter method name for column
    * <code>column</code>. This is set in the constructor.
    public boolean isCellEditable(Object node, int column) {
    return (setterMethodNames != null &&
         setterMethodNames[column] != null);
    // Note: This looks up the methods each time! This is rather inefficient;
    // it should really be changed to cache matching
    // methods/constructors
    // based on <code>node</code>'s class, and code>aValue</code>'s
    //class.
    public void setValueAt(Object aValue, Object node, int column) {
         boolean found = false;
         try {
         // We have to search through all the methods since the
         // types may not match up.
         Method[] methods = node.getClass().getMethods();
         for (int counter = methods.length - 1; counter >= 0; counter--) {
              if (methods[counter].getName().equals
              (setterMethodNames[column]) && methods[counter].
              getParameterTypes() != null && methods[counter].
              getParameterTypes().length == 1) {
              // We found a matching method
              Class param = methods[counter].getParameterTypes()[0];
              if (!param.isInstance(aValue)) {
                   // Yes, we can use the value passed in directly,
                   // no coercision is necessary!
                   if (aValue instanceof String &&
                   ((String)aValue).length() == 0) {
                   // Assume an empty string is null, this is
                   // probably bogus for here.
                   aValue = null;
                   else {
                   // Have to attempt some sort of coercision.
                   // See if the expected parameter type has
                   // a constructor that takes a String.
                   Constructor cs = param.getConstructor
                   (new Class[] { String.class });
                   if (cs != null) {
                        aValue = cs.newInstance(new Object[]
                                       { aValue });
                   else {
                        aValue = null;
              // null either means it was an empty string, or there
              // was no translation. Could potentially deal with these
              // differently.
              methods[counter].invoke(node, new Object[] { aValue });
              found = true;
              break;
         } catch (Throwable th) {
         System.out.println("exception: " + th);
         if (found) {
         // The value changed, fire an event to notify listeners.
         TreeNode parent = ((TreeNode)node).getParent();
         fireTreeNodesChanged(this, getPathToRoot(parent),
                        new int[] { getIndexOfChild(parent, node) },
                        new Object[] { node });
    public TreeNode[] getPathToRoot(TreeNode aNode) {
    return getPathToRoot(aNode, 0);
    private TreeNode[] getPathToRoot(TreeNode aNode, int depth) {
    TreeNode[] retNodes;
         // This method recurses, traversing towards the root in order
         // size the array. On the way back, it fills in the nodes,
         // starting from the root and working back to the original node.
    /* Check for null, in case someone passed in a null node, or
    they passed in an element that isn't rooted at root. */
    if(aNode == null) {
    if(depth == 0)
    return null;
    else
    retNodes = new TreeNode[depth];
    else {
    depth++;
    if(aNode == root)
    retNodes = new TreeNode[depth];
    else
    retNodes = getPathToRoot(aNode.getParent(), depth);
    retNodes[retNodes.length - depth] = aNode;
    return retNodes;
    // DynamicTreeTableModel.java END
    // IconRenderer.java BEGIN
    import java.awt.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    import javax.swing.plaf.basic.BasicTreeUI;
    class IconRenderer extends DefaultTreeCellRenderer
    // Color backColor = new Color(0xD0, 0xCC, 0xFF);
    Color backColor = new Color(0xF0, 0xF0, 0xE0);
    String tipText = "";
    JTree tree;
    int currRow = 0;
    boolean m_selected;
    JTable table;
    public IconRenderer(JTree tree, JTable table) {
    this.table = table;
    // setBackground(backColor);
    setBackground(Color.GREEN);
    setForeground(Color.black);
         this.tree = tree;
    public Component getTreeCellRendererComponent(JTree tree, Object value,
    boolean selected,
    boolean expanded, boolean leaf,
    int row, boolean hasFocus) {
         Object node = null;
         super.getTreeCellRendererComponent(
    tree, value, selected,
    expanded, leaf, row,
    hasFocus);
         TreePath treePath = tree.getPathForRow(row);
    if(treePath != null)
              node = treePath.getLastPathComponent();
    currRow = row;
    m_selected = selected;
    DefaultMutableTreeNode itc = null;
    if (node instanceof DefaultMutableTreeNode) {
    itc = (DefaultMutableTreeNode)node;
         setClosedIcon(closedIcon);
    setOpenIcon(openIcon);
    return this;
    /* Override the default to send back different strings for folders and leaves. */
    public String getToolTipText() {
    return tipText;
    * Paints the value. The background is filled based on selected.
    public void paint(Graphics g) {
         super.paint(g);
         Color bColor = null;
         if(!m_selected) {
              System.out.println(" iconren not sel currRow " + currRow);
              if(currRow % 2 == 0) {
                   bColor = Color.WHITE;
              } else {
              bColor = backColor;
         } else {
              bColor = table.getSelectionBackground();
              System.out.println("in else selbg = " + bColor);           
              bColor = new Color(0xF0, 0xCC, 0x92);
              System.out.println(" bColor aft = " + bColor);           
         int imageOffset = -1;
         if(bColor != null) {
         imageOffset = getLabelStart();
         g.setColor(bColor);
         if(!m_selected) {
              System.out.println(" not sel setting white ");
              g.setXORMode(new Color(0xFF, 0xFF, 0xFF));
         } else {
    //          g.setXORMode(new Color(0xCC, 0xCC, 0x9F));
              g.setXORMode(new Color(0x00, 0x00, 0x00));
              System.out.println(" using color = " + g.getColor());           
         if(getComponentOrientation().isLeftToRight()) {
         g.fillRect(imageOffset, 0, getWidth() - 1 - imageOffset,
                   getHeight());
         } else {
         g.fillRect(0, 0, getWidth() - 1 - imageOffset,
                   getHeight());
    private int getLabelStart() {
         Icon currentI = getIcon();
         if(currentI != null && getText() != null) {
         return currentI.getIconWidth() + Math.max(0, getIconTextGap() - 1);
         return 0;
    // IconRenderer.java END
    // IndicatorRenderer.java BEGIN
    // import java.awt.*;
    import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.event.*;
    import javax.swing.tree.*;
    import javax.swing.table.*;
    import javax.swing.table.*;
    import javax.swing.plaf.basic.*;
    import java.awt.event.*;
    import java.util.EventObject;
    import java.text.NumberFormat;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.StringTokenizer;
    import java.util.Arrays;
    class IndicatorRenderer extends DefaultTableCellRenderer {
    /** Makes sure the number of displayed in an internationalized
    * manner. */
    protected NumberFormat formatter;
    /** Row that is currently being painted. */
    protected int lastRow;
    protected int reloadRow;
    protected int reloadCounter;
    protected TreeTableModel treeTableModel;
    protected TreeTableModelAdapter treeTblAdapter;
    protected JTable table;
    Component renderer = null;
    Color backColor = new Color(0xF0, 0xF0, 0xE0);
    IndicatorRenderer(TreeTableModelAdapter treeTblAdapter, TreeTableModel treeTableModel) {
         setHorizontalAlignment(JLabel.RIGHT);
         setFont(new Font("serif", Font.BOLD, 12));
         this.treeTableModel = treeTableModel;
         this.treeTblAdapter = treeTblAdapter;
    * Invoked as part of DefaultTableCellRenderers implemention. Sets
    * the text of the label.
    public void setValue(Object value) {
    /* setText((value == null) ? "---" : formatter.format(value)); */
         setText((value == null) ? "---" : (String) value.toString());
    * Returns this.
    public Component getTableCellRendererComponent(JTable table,
    Object value, boolean isSelected, boolean hasFocus,
    int row, int column) {
         renderer = super.getTableCellRendererComponent(table, value, isSelected,
    hasFocus, row, column);
         lastRow = row;
         this.table = table;
              if(isSelected) {
                   doMask(hasFocus, isSelected);
              } else
              setBackground(table.getBackground());
    return renderer;
    * If the row being painted is also being reloaded this will draw
    * a little indicator.
    public void paint(Graphics g) {
         super.paint(g);
    private void doMask(boolean hasFocus, boolean selected) {
              maskBackground(hasFocus, selected);
    private void maskBackground(boolean hasFocus, boolean selected) {
              Color seed = null;
              seed = table.getSelectionBackground();
              Color color = seed;
              if (color != null) {
                   setBackground(
    new Color(0xF0, 0xCC, 0x92));
    // IndicatorRenderer.java END
    // JTreeTable.java BEGIN
    import java.awt.*;
    import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.event.*;
    import javax.swing.tree.*;
    import javax.swing.table.*;
    import java.awt.event.*;
    import java.util.EventObject;
    public class JTreeTable extends JTable {
    /** A subclass of JTree. */
    protected TreeTableCellRenderer tree;
    protected IndicatorRenderer indicatorRenderer = null;
    public JTreeTable(TreeTableModel treeTableModel) {
         super();
         // Creates the tree. It will be used as a renderer and editor.
         tree = new TreeTableCellRenderer(treeTableModel);
         TreeTableModelAdapter tdap = new TreeTableModelAdapter(treeTableModel, tree);
         // Installs a tableModel representing the visible rows in the tree.
         super.setModel(tdap);
         // Forces the JTable and JTree to share their row selection models.
         ListToTreeSelectionModelWrapper selectionWrapper = new
         ListToTreeSelectionModelWrapper();
         tree.setSelectionModel(selectionWrapper);
         setSelectionModel(selectionWrapper.getListSelectionModel());
         // Installs the tree editor renderer and editor.
         setDefaultRenderer(TreeTableModel.class, tree);
         setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor());
         indicatorRenderer = new IndicatorRenderer(tdap, treeTableModel);     
         // No grid.
         setShowGrid(false);
         // No intercell spacing
         setIntercellSpacing(new Dimension(0, 0));     
         // And update the height of the trees row to match that of
         // the table.
         //if (tree.getRowHeight() < 1) {
         // Metal looks better like this.
         setRowHeight(20);
    public TableCellRenderer getCellRenderer(int row, int col) {
              if(col == 0)
              return tree;
              else
              return indicatorRenderer;     
    public void updateUI() {
         super.updateUI();
         if(tree != null) {
         tree.updateUI();
         // Do this so that the editor is referencing the current renderer
         // from the tree. The renderer can potentially change each time
         // laf changes.
         setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor());
         // Use the tree's default foreground and background colors in the
         // table.
    LookAndFeel.installColorsAndFont(this, "Tree.background",
    "Tree.foreground", "Tree.font");
    public int getEditingRow() {
    return (getColumnClass(editingColumn) == TreeTableModel.class) ? -1 :
         editingRow;
    private int realEditingRow() {
         return editingRow;
    public void sizeColumnsToFit(int resizingColumn) {
         super.sizeColumnsToFit(resizingColumn);
         if (getEditingColumn() != -1 && getColumnClass(editingColumn) ==
         TreeTableModel.class) {
         Rectangle cellRect = getCellRect(realEditingRow(),
                             getEditingColumn(), false);
    Component component = getEditorComponent();
         component.setBounds(cellRect);
    component.validate();
    public void setRowHeight(int rowHeight) {
    super.setRowHeight(rowHeight);
         if (tree != null && tree.getRowHeight() != rowHeight) {
    tree.setRowHeight(getRowHeight());
    public JTree getTree() {
         return tree;
    public boolean editCellAt(int row, int column, EventObject e){
         boolean retValue = super.editCellAt(row, column, e);
         if (retValue && getColumnClass(column) == TreeTableModel.class) {
         repaint(getCellRect(row, column, false));
         return retValue;
    public class TreeTableCellRenderer extends JTree implements
         TableCellRenderer {
         /** Last table/tree row asked to renderer. */
         protected int visibleRow;
         /** Border to draw around the tree, if this is non-null, it will
         * be painted. */
         protected Border highlightBorder;
         public TreeTableCellRenderer(Tr

  • How to get a pop-up menu on right click of JTree?

    hi
    My application consists of a JTree.I am having a 2 root nodes each one have some child nodes.in the first root node what i want is on right click of child node i have to display one option that is enabled and on the second root node what i want is on right click of child node i have to display one option that is disabled..
    how to do that
    thanks for your reply in advance,

    When you are creating your nodes, do node.setUserObject(objectName);
    and on right click, do something like this
    if (e.isPopupTrigger() == true) {
             selPath = tree.getPathForLocation(e.getX(), e.getY());
          try {
             // If Right Click, Select the Node
             Object[] selectedPath = selPath.getPath();
             DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) selectedPath[selectedPath.length - 1];
             try {
                dataObject = (MyObject) selectedNode.getUserObject(); // Set the Data Object
             } catch (ClassCastException ex) {
                                      ex.printStackTrace();
             // Check for the right click on Framework Node
             if (dataObject.getClass().isInstance(new MyObject()) == true) {
                // Disable the pop-up menu
    ....

  • JTree with XML Content

    Hi Friends,
    I am trying to create a JTree whose data will come from a XML Document. Whenever the tree is refreshed (There is a JPopupMenu on the tree which allows the user to call refresh), the tree must update itself with the underlying XML document. If there is any change in the xml doc, it must be reflected in the tree. However, the tree must not collapse when the refresh is called. For example if I have a tree like this:-
    + Root
        |
        ------ Child #1
        |            |
        |            -------- A
        |            |
        |            -------- B
        |
        +------ Child #2
        |
        ------- Child #3
                    |
                    -------- AAA
                    |
                    -------- BBBThe XML Document for the above tree structure would be:-
    <?xml version="1.0" encoding="UTF-8"?>
    <Root>Root
          <Child> Child #1
                <SubChild>A</SubChild>
                <SubChild>B</SubChild>
          </Child>
          <Child> Child #2
                <SubChild>AA</SubChild>
                <SubChild>BB</SubChild>
          </Child>
          <Child> Child #3
                <SubChild>AAA</SubChild>
                <SubChild>BBB</SubChild>
          </Child>
    </Root>Now if i add another node (CCC) in Child #3 (by adding another Subchild element in the XML document), and click refresh on the tree, the tree should look like:-
    + Root
        |
        ------ Child #1
        |            |
        |            -------- A
        |            |
        |            -------- B
        |
        +------ Child #2
        |
        ------- Child #3
                    |
                    -------- AAA
                    |
                    -------- BBB
                    |
                    -------- CCCHowever, if i am trying to reload the tree model, after reading the XML file, the whole tree collapses.
    Can anyone please help me out with this problem?
    Thanx a lot in advance,
    ~Debopam

    * XMLNode.java
    * Created on December 18, 2004, 4:25 PM
    package debopam.utils.xml;
    import java.util.Enumeration;
    import java.util.NoSuchElementException;
    import java.util.Vector;
    import javax.swing.tree.MutableTreeNode;
    import javax.swing.tree.TreeNode;
    import org.jdom.Element;
    * @author Debopam Ghoshal
    public class XMLNode implements MutableTreeNode
        private Element nodeElement;
        private XMLNode parent;
        /** optional user object */
        transient protected Object     userObject;
        /** true if the node is able to have children */
        protected boolean allowsChildren;
        /** array of children, may be null if this node has no children */
        protected Vector children;
         * An enumeration that is always empty. This is used when an enumeration
         * of a leaf node's children is requested.
        static public final Enumeration<TreeNode> EMPTY_ENUMERATION
                = new Enumeration<TreeNode>()
            public boolean hasMoreElements()
            { return false; }
            public TreeNode nextElement()
                throw new NoSuchElementException("No more elements");
        /** Creates a new instance of XMLNode */
        public XMLNode(Element nodeElement, boolean allowsChildren)
            this.nodeElement = nodeElement;
            this.allowsChildren = allowsChildren;
        public XMLNode(String nodeName, boolean allowsChildren)
            nodeElement = new Element(nodeName);
            this.allowsChildren = allowsChildren;
         * Creates and returns a forward-order enumeration of this node's
         * children.  Modifying this node's child array invalidates any child
         * enumerations created before the modification.
         * @return     an Enumeration of this node's children
        public java.util.Enumeration children()
            if(children == null)
                return EMPTY_ENUMERATION;
            else
                return children.elements();
         * Returns true if this node is allowed to have children.
         * @return     true if this node allows children, else false
        public boolean getAllowsChildren()
            return allowsChildren;
         * Determines whether or not this node is allowed to have children.
         * If <code>allows</code> is false, all of this node's children are
         * removed.
         * <p>
         * Note: By default, a node allows children.
         * @param     allows     true if this node is allowed to have children
        public void setAllowsChildren(boolean allows)
            if (allows != allowsChildren)
                allowsChildren = allows;
                if (!allowsChildren)
                    removeAllChildren();
         * Returns the child at the specified index in this node's child array.
         * @param     index     an index into this node's child array
         * @exception     ArrayIndexOutOfBoundsException     if <code>index</code>
         *                              is out of bounds
         * @return     the TreeNode in this node's child array at  the specified index
        public javax.swing.tree.TreeNode getChildAt(int index)
            if (children == null)
                throw new ArrayIndexOutOfBoundsException("node has no children");
            return (TreeNode)children.elementAt(index);
         * Returns the number of children of this node.
         * @return     an int giving the number of children of this node
        public int getChildCount()
            if (children == null)
                return 0;
            else
                return children.size();
         * Returns the index of the specified child in this node's child array.
         * If the specified node is not a child of this node, returns
         * <code>-1</code>.  This method performs a linear search and is O(n)
         * where n is the number of children.
         * @param     aChild     the TreeNode to search for among this node's children
         * @exception     IllegalArgumentException     if <code>aChild</code>
         *                                   is null
         * @return     an int giving the index of the node in this node's child
         *          array, or <code>-1</code> if the specified node is a not
         *          a child of this node
        public int getIndex(TreeNode aChild)
            if (aChild == null)
                throw new IllegalArgumentException("argument is null");
            if (!isNodeChild(aChild))
                return -1;
            return children.indexOf(aChild);     // linear search
         * Returns this node's parent or null if this node has no parent.
         * @return     this node's parent TreeNode, or null if this node has no parent
        public TreeNode getParent()
            return parent;
         * Removes <code>newChild</code> from its present parent (if it has a
         * parent), sets the child's parent to this node, and then adds the child
         * to this node's child array at index <code>childIndex</code>.
         * <code>newChild</code> must not be null and must not be an ancestor of
         * this node.
         * @param     newChild     the MutableTreeNode to insert under this node
         * @param     childIndex     the index in this node's child array
         *                    where this node is to be inserted
         * @exception     ArrayIndexOutOfBoundsException     if
         *                    <code>childIndex</code> is out of bounds
         * @exception     IllegalArgumentException     if
         *                    <code>newChild</code> is null or is an
         *                    ancestor of this node
         * @exception     IllegalStateException     if this node does not allow
         *                              children
         * @see     #isNodeDescendant
        public void insert(MutableTreeNode newChild, int childIndex)
            if (!allowsChildren)
                throw new IllegalStateException("node does not allow children");
            else if (newChild == null)
                throw new IllegalArgumentException("new child is null");
            else if (isNodeAncestor(newChild))
                throw new IllegalArgumentException("new child is an ancestor");
            MutableTreeNode oldParent = (MutableTreeNode)newChild.getParent();
            if (oldParent != null)
                oldParent.remove(newChild);
            newChild.setParent(this);
            if (children == null)
                children = new Vector();
            children.insertElementAt(newChild, childIndex);
        public boolean isLeaf()
            return !nodeElement.hasChildren();
         * Removes the child at the specified index from this node's children
         * and sets that node's parent to null. The child node to remove
         * must be a <code>MutableTreeNode</code>.
         * @param     childIndex     the index in this node's child array
         *                    of the child to remove
         * @exception     ArrayIndexOutOfBoundsException     if
         *                    <code>childIndex</code> is out of bounds
        public void remove(int childIndex)
            MutableTreeNode child = (MutableTreeNode)getChildAt(childIndex);
            children.removeElementAt(childIndex);
            child.setParent(null);
         * Removes <code>aChild</code> from this node's child array, giving it a
         * null parent.
         * @param     aChild     a child of this node to remove
         * @exception     IllegalArgumentException     if <code>aChild</code>
         *                         is null or is not a child of this node
        public void remove(MutableTreeNode aChild)
            if (aChild == null)
                throw new IllegalArgumentException("argument is null");
            if (!isNodeChild(aChild))
                throw new IllegalArgumentException("argument is not a child");
            remove(getIndex(aChild));     // linear search
         * Removes the subtree rooted at this node from the tree, giving this
         * node a null parent.  Does nothing if this node is the root of its
         * tree.
        public void removeFromParent()
            MutableTreeNode parent = (MutableTreeNode)getParent();
            if (parent != null)
                parent.remove(this);
         * Sets this node's parent to <code>newParent</code> but does not
         * change the parent's child array.  This method is called from
         * <code>insert()</code> and <code>remove()</code> to
         * reassign a child's parent, it should not be messaged from anywhere
         * else.
         * @param     newParent     this node's new parent
        public void setParent(MutableTreeNode mutableTreeNode)
            this.parent = parent;
        public void setUserObject(Object obj)
            this.userObject = obj;
        public Element getXMLElement()
            return this.nodeElement;
        public String toString()
            return this.nodeElement.getTextTrim();
         * Returns true if <code>anotherNode</code> is an ancestor of this node
         * -- if it is this node, this node's parent, or an ancestor of this
         * node's parent.  (Note that a node is considered an ancestor of itself.)
         * If <code>anotherNode</code> is null, this method returns false.  This
         * operation is at worst O(h) where h is the distance from the root to
         * this node.
         * @see          #isNodeDescendant
         * @see          #getSharedAncestor
         * @param     anotherNode     node to test as an ancestor of this node
         * @return     true if this node is a descendant of <code>anotherNode</code>
        public boolean isNodeAncestor(TreeNode anotherNode)
            if (anotherNode == null)
                return false;
            TreeNode ancestor = this;
            do
                if (ancestor == anotherNode)
                    return true;
            } while((ancestor = ancestor.getParent()) != null);
            return false;
         * Returns true if <code>aNode</code> is a child of this node.  If
         * <code>aNode</code> is null, this method returns false.
         * @return     true if <code>aNode</code> is a child of this node; false if
         *            <code>aNode</code> is null
        public boolean isNodeChild(TreeNode aNode)
            boolean retval;
            if (aNode == null)
                retval = false;
            else
                if (getChildCount() == 0)
                    retval = false;
                else
                    retval = (aNode.getParent() == this);
            return retval;
         * Removes all of this node's children, setting their parents to null.
         * If this node has no children, this method does nothing.
        public void removeAllChildren()
            for (int i = getChildCount()-1; i >= 0; i--)
                remove(i);
         * Removes <code>newChild</code> from its parent and makes it a child of
         * this node by adding it to the end of this node's child array.
         * @see          #insert
         * @param     newChild     node to add as a child of this node
         * @exception     IllegalArgumentException    if <code>newChild</code>
         *                              is null
         * @exception     IllegalStateException     if this node does not allow
         *                              children
        public void add(MutableTreeNode newChild)
            if(newChild != null && newChild.getParent() == this)
                insert(newChild, getChildCount() - 1);
            else
                insert(newChild, getChildCount());
         * Indicates whether some other object is "equal to" this one.
         * @param   obj   the reference object with which to compare.
         * @return  <code>true</code> if this object is the same as the obj
         *          argument; <code>false</code> otherwise.
        public boolean equals(XMLNode node)
            boolean retValue;
            retValue = (this.getXMLElement().getTextTrim().equals(node.getXMLElement().getTextTrim())) &&
                    (this.getXMLElement().getParent().getTextTrim().equals(node.getXMLElement().getParent().getTextTrim()));
            return retValue;
    * XMLTreeModel.java
    * Created on December 20, 2004, 11:29 AM
    package debopam.utils.xml;
    import java.io.File;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    import java.util.EventListener;
    import java.util.List;
    import java.util.Vector;
    import javax.swing.event.EventListenerList;
    import javax.swing.event.TreeModelEvent;
    import javax.swing.event.TreeModelListener;
    import javax.swing.tree.TreeModel;
    import javax.swing.tree.TreePath;
    import org.jdom.Document;
    import org.jdom.Element;
    import org.jdom.input.SAXBuilder;
    * @author Debopam Ghoshal
    public class XMLTreeModel implements TreeModel
        private XMLNode rootNode;
        private String xmlFileName;
        private Document xmlDocument;
        /** Listeners. */
        protected EventListenerList listenerList = new EventListenerList();
         * Determines how the <code>isLeaf</code> method figures
         * out if a node is a leaf node. If true, a node is a leaf
         * node if it does not allow children. (If it allows
         * children, it is not a leaf node, even if no children
         * are present.) That lets you distinguish between <i>folder</i>
         * nodes and <i>file</i> nodes in a file system, for example.
         * <p>
         * If this value is false, then any node which has no
         * children is a leaf node, and any node may acquire
         * children.
         * @see TreeNode#getAllowsChildren
         * @see TreeModel#isLeaf
         * @see #setAsksAllowsChildren
        protected boolean asksAllowsChildren;
        /** Creates a new instance of XMLTreeModel */
        public XMLTreeModel(String xmlFileName, boolean asksAllowsChildren)
            this.xmlFileName = xmlFileName;
            this.asksAllowsChildren = asksAllowsChildren;
            loadXMLDocument();
            rootNode = makeRootNode();
        public XMLTreeModel(String xmlFileName)
            this(xmlFileName, false);
        private void loadXMLDocument()
            System.out.println("loading xml document...");
            try
                this.xmlDocument = null;
                this.xmlDocument = new SAXBuilder().build(new File(xmlFileName));
            catch(Exception x)
                System.out.println("Error while loading XML Document.");
                x.printStackTrace();
        private XMLNode makeRootNode()
            XMLNode root = new XMLNode(xmlDocument.getRootElement(), true);
            addChildren(root, xmlDocument.getRootElement());
            return root;
        private void addChildren(XMLNode parentXMLNode, Element element)
            List children = element.getChildren();
            for(int i = 0; i < children.size(); i++)
                Element childElement = (Element)children.get(i);
                XMLNode childNode = new XMLNode(childElement, true);
                parentXMLNode.add(childNode);
                addChildren(childNode, childElement);
         * Sets whether or not to test leafness by asking getAllowsChildren()
         * or isLeaf() to the TreeNodes.  If newvalue is true, getAllowsChildren()
         * is messaged, otherwise isLeaf() is messaged.
        public void setAsksAllowsChildren(boolean newValue)
            asksAllowsChildren = newValue;
         * Tells how leaf nodes are determined.
         * @return true if only nodes which do not allow children are
         *         leaf nodes, false if nodes which have no children
         *         (even if allowed) are leaf nodes
         * @see #asksAllowsChildren
        public boolean asksAllowsChildren()
            return asksAllowsChildren;
         * Returns the child of <I>parent</I> at index <I>index</I> in the parent's
         * child array.  <I>parent</I> must be a node previously obtained from
         * this data source. This should not return null if <i>index</i>
         * is a valid index for <i>parent</i> (that is <i>index</i> >= 0 &&
         * <i>index</i> < getChildCount(<i>parent</i>)).
         * @param   parent  a node in the tree, obtained from this data source
         * @return  the child of <I>parent</I> at index <I>index</I>
        public Object getChild(Object parent, int index)
            return ((XMLNode)parent).getChildAt(index);
         * Returns the number of children of <I>parent</I>.  Returns 0 if the node
         * is a leaf or if it has no children.  <I>parent</I> must be a node
         * previously obtained from this data source.
         * @param   parent  a node in the tree, obtained from this data source
         * @return  the number of children of the node <I>parent</I>
        public int getChildCount(Object parent)
            return ((XMLNode)parent).getChildCount();
         * Returns the index of child in parent.
         * If either the parent or child is <code>null</code>, returns -1.
         * @param parent a note in the tree, obtained from this data source
         * @param child the node we are interested in
         * @return the index of the child in the parent, or -1
         *    if either the parent or the child is <code>null</code>
        public int getIndexOfChild(Object parent, Object child)
            if(parent == null || child == null)
                return -1;
            return ((XMLNode)parent).getIndex((XMLNode)child);
         * Sets the root to <code>root</code>. A null <code>root</code> implies
         * the tree is to display nothing, and is legal.
        public void setRoot(XMLNode rootNode)
            Object oldRoot = this.rootNode;
            this.rootNode = rootNode;
            if (rootNode == null && oldRoot != null)
                fireTreeStructureChanged(this, null);
            else
                nodeStructureChanged(rootNode);
         * Returns the root of the tree.  Returns null only if the tree has
         * no nodes.
         * @return  the root of the tree
        public Object getRoot()
            return rootNode;
         * Returns whether the specified node is a leaf node.
         * The way the test is performed depends on the
         * <code>askAllowsChildren</code> setting.
         * @param node the node to check
         * @return true if the node is a leaf node
         * @see #asksAllowsChildren
         * @see TreeModel#isLeaf
        public boolean isLeaf(Object node)
            if(asksAllowsChildren)
                return !((XMLNode)node).getAllowsChildren();
            return ((XMLNode)node).isLeaf();
         * This sets the user object of the TreeNode identified by path
         * and posts a node changed.  If you use custom user objects in
         * the TreeModel you're going to need to subclass this and
         * set the user object of the changed node to something meaningful.
        public void valueForPathChanged(TreePath path, Object newValue)
            XMLNode aNode = (XMLNode)path.getLastPathComponent();
            aNode.setUserObject(newValue);
            nodeChanged(aNode);
         * Invoked this to insert newChild at location index in parents children.
         * This will then message nodesWereInserted to create the appropriate
         * event. This is the preferred way to add children as it will create
         * the appropriate event.
        public void insertNodeInto(XMLNode newChild, XMLNode parent, int index)
            parent.insert(newChild, index);
            int[] newIndexs = new int[1];
            newIndexs[0] = index;
            nodesWereInserted(parent, newIndexs);
         * Message this to remove node from its parent. This will message
         * nodesWereRemoved to create the appropriate event. This is the
         * preferred way to remove a node as it handles the event creation
         * for you.
        public void removeNodeFromParent(XMLNode node)
            XMLNode parent = (XMLNode)node.getParent();
            if(parent == null)
                throw new IllegalArgumentException("node does not have a parent.");
            int[] childIndex = new int[1];
            Object[] removedArray = new Object[1];
            childIndex[0] = parent.getIndex(node);
            parent.remove(childIndex[0]);
            removedArray[0] = node;
            nodesWereRemoved(parent, childIndex, removedArray);
         * Invoke this method after you've changed how node is to be
         * represented in the tree.
        public void nodeChanged(XMLNode node)
            if(listenerList != null && node != null)
                XMLNode parent = (XMLNode)node.getParent();
                if(parent != null)
                    int        anIndex = parent.getIndex(node);
                    if(anIndex != -1)
                        int[] cIndexs = new int[1];
                        cIndexs[0] = anIndex;
                        nodesChanged(parent, cIndexs);
                else if (node == getRoot())
                    nodesChanged(node, null);
         * Invoke this method if you've modified the TreeNodes upon which this
         * model depends.  The model will notify all of its listeners that the
         * model has changed.
        public void reload()
            loadXMLDocument();
            XMLNode tempRootNode = makeRootNode();
            if(!tempRootNode.equals(rootNode))
                // Means that the root node itself has changed.
                System.out.println("Root node changed");
                reload(rootNode);
            //else
                checkForNodesChanged(tempRootNode, rootNode);
         * Invoke this method if you've modified the TreeNodes upon which this
         * model depends.  The model will notify all of its listeners that the
         * model has changed below the node <code>node</code> (PENDING).
        public void reload(XMLNode node)
            if(node != null)
                fireTreeStructureChanged(this, getPathToRoot(node), null, null);
         * Invoke this method after you've inserted some TreeNodes into
         * node.  childIndices should be the index of the new elements and
         * must be sorted in ascending order.
        public void nodesWereInserted(XMLNode node, int[] childIndices)
            if(listenerList != null && node != null && childIndices != null
                    && childIndices.length > 0)
                int               cCount = childIndices.length;
                Object[]          newChildren = new Object[cCount];
                for(int counter = 0; counter < cCount; counter++)
                    newChildren[counter] = node.getChildAt(childIndices[counter]);
                fireTreeNodesInserted(this, getPathToRoot(node), childIndices,
                        newChildren);
         * Invoke this method after you've removed some TreeNodes from
         * node.  childIndices should be the index of the removed elements and
         * must be sorted in ascending order. And removedChildren should be
         * the array of the children objects that were removed.
        public void nodesWereRemoved(XMLNode node, int[] childIndices,
                Object[] removedChildren)
            if(node != null && childIndices != null)
                fireTreeNodesRemoved(this, getPathToRoot(node), childIndices,
                        removedChildren);
         * Invoke this method after you've changed how the children identified by
         * childIndicies are to be represented in the tree.
        public void nodesChanged(XMLNode node, int[] childIndices)
            if(node != null)
                if (childIndices != null)
                    int cCount = childIndices.length;
                    if(cCount > 0)
                        Object[] cChildren = new Object[cCount];
                        for(int counter = 0; counter < cCount; counter++)
                            cChildren[counter] = node.getChildAt
                                    (childIndices[counter]);
                        fireTreeNodesChanged(this, getPathToRoot(node),
                                childIndices, cChildren);
                else if (node == getRoot())
                    fireTreeNodesChanged(this, getPathToRoot(node), null, null);
         * Invoke this method if you've totally changed the children of
         * node and its childrens children...  This will post a
         * treeStructureChanged event.
        public void nodeStructureChanged(XMLNode node)
            if(node != null)
                fireTreeStructureChanged(this, getPathToRoot(node), null, null);
         * Builds the parents of node up to and including the root node,
         * where the original node is the last element in the returned array.
         * The length of the returned array gives the node's depth in the
         * tree.
         * @param aNode the TreeNode to get the path for
        public XMLNode[] getPathToRoot(XMLNode aNode)
            return getPathToRoot(aNode, 0);
         * Builds the parents of node up to and including the root node,
         * where the original node is the last element in the returned array.
         * The length of the returned array gives the node's depth in the
         * tree.
         * @param aNode  the TreeNode to get the path for
         * @param depth  an int giving the number of steps already taken towards
         *        the root (on recursive calls), used to size the returned array
         * @return an array of TreeNodes giving the path from the root to the
         *         specified node
        protected XMLNode[] getPathToRoot(XMLNode aNode, int depth)
            XMLNode[] retNodes;
            // This method recurses, traversing towards the root in order
            // size the array. On the way back, it fills in the nodes,
            // starting from the root and working back to the original node.
            /* Check for null, in case someone passed in a null node, or
               they passed in an element that isn't rooted at root. */
            if(aNode == null)
                if(depth == 0)
                    return null;
                else
                    retNodes = new XMLNode[depth];
            else
                depth++;
                if(aNode == rootNode)
                    retNodes = new XMLNode[depth];
                else
                    retNodes = getPathToRoot((XMLNode)aNode.getParent(), depth);
                retNodes[retNodes.length - depth] = aNode;
            return retNodes;
        //  Events
         * Adds a listener for the TreeModelEvent posted after the tree changes.
         * @see     #removeTreeModelListener
         * @param   l       the listener to add
        public void addTreeModelListener(TreeModelListener l)
            listenerList.add(TreeModelListener.class, l);
         * Removes a listener previously added with <B>addTreeModelListener()</B>.
         * @see     #addTreeModelListener
         * @param   l       the listener to remove
        public void removeTreeModelListener(TreeModelListener l)
            listenerList.remove(TreeModelListener.class, l);
         * Returns an array of all the tree model listeners
         * registered on this model.
         * @return all of this model's <code>TreeModelListener</code>s
         *         or an empty
         *         array if no tree model listeners are currently registered
         * @see #addTreeModelListener
         * @see #removeTreeModelListener
         * @since 1.4
        public TreeModelListener[] getTreeModelListeners()
            return (TreeModelListener[])listenerList.getListeners(
                    TreeModelListener.class);
         * Notifies all listeners that have registered interest for
         * notification on this event type.  The event instance
         * is lazily created using the parameters passed into
         * the fire method.
         * @param source the node being changed
         * @param path the path to the root node
         * @param childIndices the indices of the changed elements
         * @param children the changed elements
         * @see EventListenerList
        protected void fireTreeNodesChanged(Object source, Object[] path,
                int[] childIndices,
                Object[] children)
            // Guaranteed to return a non-null array
            Object[] listeners = listenerList.getListenerList();
            TreeModelEvent e = null;
            // Process the listeners last to first, notifying
            // those that are interested in this event
            for (int i = listeners.length-2; i>=0; i-=2)
                if (listeners==TreeModelListener.class)
    // Lazily create the event:
    if (e == null)
    e = new TreeModelEvent(source, path,
    childIndices, children);
    ((TreeModelListener)listeners[i+1]).treeNodesChanged(e);
    * Notifies all listeners that have registered interest for
    * notification on this event type. The event instance

  • Runtime dynamic filtering TreeModel

    Hello,
    Changing a tree during runtime seems to be a problem. I've looked at different threads and now I have the following class which filters a delegated DefaultTreeModel (see SimpleFilteredTreeModel and the corresponding TestFilteredTreeModel classes below). Notice, that the commented lines in the isShown-method do filter out alternaitve objects behind the tree at startup of the application correctly.
    I used the following two steps to extend the SimpleFilteredTreeModel to make it refreshing dynamically:
    1. Step: ViewFilter Interface
    First I enabled the SimpleFilteredTreeModel to set filter roules dynamically by introducing an interface (ViewFilter) and three implementions according to the alternatives shown in the isShown method. The filter is set by a method setViewFilter(ViewFilter).
    2. Step: Update the Model
    The method setViewFilter(ViewFilter) basically sets the new filter and tries to update the model so it shows up under the new behaviour.
        public void setViewFilter(ViewFilter filter) {
            this.filter = filter;
            // Notify the model
            final TreeNode root = (TreeNode) getRoot();
            final int childCount = root.getChildCount();
            final int[] indices = new int[childCount];
            final Object[] children = new Object[childCount];
            for (int i = 0; i < childCount; i++) {
                indices[i] = i;
                children[i] = getChild(root, i);
            fireTreeStructureChanged(this, new Object[]{root}, indices, children);
        }However, the view does not move at all. I tried also reload() and nodeChange(root) of the filter model and its delegate. No success.
    If somebody knows how to extend this example to work dynamically, I would appreciate it highly.
    -- Thanks
    -- Daniel Frey
    // File: SimpleFilteredTreeModel.java
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.DefaultTreeModel;
    import javax.swing.tree.TreeNode;
    public class SimpleFilteredTreeModel extends DefaultTreeModel {
        private DefaultTreeModel delegate;
        public SimpleFilteredTreeModel(DefaultTreeModel delegate) {
            super((TreeNode) delegate.getRoot());
            this.delegate = delegate;
        public Object getChild(Object parent, int index) {
            int count = 0;
            for (int i = 0; i < delegate.getChildCount(parent); i++) {
                final Object child = delegate.getChild(parent, i);
                if (isShown(child)) {
                    if (count++ == index) {
                        return child;
                else {
                    final Object child2 = getChild(child, index - count);
                    if (child2 != null) {
                        return child2;
                    count += getChildCount(child);
            return null;
        public int getIndexOfChild(Object parent, Object child) {
            return delegate.getIndexOfChild(parent, child);
        public int getChildCount(Object parent) {
            int count = 0;
            for (int i = 0; i < delegate.getChildCount(parent); i++) {
                final Object child = delegate.getChild(parent, i);
                if (isShown(child)) {
                    count++;
                else {
                    count += getChildCount(child);
            return count;
        public boolean isLeaf(Object node) {
            return delegate.isLeaf(node);
        private boolean isShown(Object node) {
            final DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
            final Object obj = treeNode.getUserObject();
            //return obj instanceof TestFilteredTreeModel.Datum1 || obj instanceof TestFilteredTreeModel.Datum2;
            //return obj instanceof TestFilteredTreeModel.Datum1;
            return obj instanceof TestFilteredTreeModel.Datum2;
    // File: TestFilteredTreeModel
    import java.util.Arrays;
    import java.util.List;
    import java.util.Random;
    import java.util.ArrayList;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.MutableTreeNode;
    import javax.swing.tree.TreeNode;
    import javax.swing.tree.TreeModel;
    import javax.swing.tree.DefaultTreeModel;
    import javax.swing.JTree;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    public class TestFilteredTreeModel {
        private DefaultMutableTreeNode[] nodes = new DefaultMutableTreeNode[0];
        public static void main(String[] args) {
            new TestFilteredTreeModel();
        public TestFilteredTreeModel() {
            final TreeNode root = createRootNode();
            final TreeModel model = new SimpleFilteredTreeModel(new DefaultTreeModel(root));
            final JTree tree = new JTree(model);
            final JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.getContentPane().add(new JScrollPane(tree));
            f.setSize(200, 300);
            f.setVisible(true);
        // Random tree generation
        private Random random = new Random();
        private TreeNode createRootNode() {
            final MutableTreeNode rootNode = createRandomNode();
            updateCache(rootNode);
            for (int i = 0; i < 30; i++) {
                final DefaultMutableTreeNode childNode = createRandomNode();
                pickRandom(nodes).add(childNode);
                updateCache(childNode);
            return rootNode;
        private void updateCache(MutableTreeNode childNode) {
            final List list = new ArrayList(Arrays.asList(nodes));
            list.add(childNode);
            nodes = (DefaultMutableTreeNode[]) list.toArray(new DefaultMutableTreeNode[0]);
        private DefaultMutableTreeNode createRandomNode() {
            final Datum[] data = new Datum[]{new Datum2(), new Datum1()};
            return new DefaultMutableTreeNode(data[random.nextInt(2)]);
        private DefaultMutableTreeNode pickRandom(DefaultMutableTreeNode[] nodes) {
            return nodes[random.nextInt(nodes.length)];
        public static class Datum {
            private static int counter = 0;
            protected int thisCounter = 0;
            public Datum() {
                thisCounter = counter++;
        public static class Datum2 extends Datum {
            public String toString() {
                return "Datum2 " + thisCounter;
        public static class Datum1 extends Datum {
            public String toString() {
                return "Datum1 " + thisCounter;
    // file: ViewFilter.java
    import javax.swing.tree.DefaultMutableTreeNode;
    public interface ViewFilter {
        boolean isShown(DefaultMutableTreeNode node);
    // file: Data1Filter.java
    import javax.swing.tree.DefaultMutableTreeNode;
    public class Data1Filter implements ViewFilter {
        public boolean isShown(DefaultMutableTreeNode node) {
            final Object obj = node.getUserObject();
            return obj instanceof TestFilteredTreeModel.Datum1;
    // file: Data2Filter.java
    import javax.swing.tree.DefaultMutableTreeNode;
    public class Data2Filter implements ViewFilter {
        public boolean isShown(DefaultMutableTreeNode node) {
            final Object obj = node.getUserObject();
            return obj instanceof TestFilteredTreeModel.Datum2;
    // file: Data12Filter.java
    import javax.swing.tree.DefaultMutableTreeNode;
    public class Data12Filter implements ViewFilter {
        public boolean isShown(DefaultMutableTreeNode node) {
            final Object obj = node.getUserObject();
            return obj instanceof TestFilteredTreeModel.Datum1 || obj instanceof TestFilteredTreeModel.Datum2;
    }

    The filtering works (after a fasion). Please clarify your problem.
    I extended SimpleFitleredTreeModel as you described, along with changing isLeaf to use the filter
    if (filter != null)  return filter.isShown( treeNode );I extended TestFiltredTreeModel constructor as follows, add the member
    import javax.swing.*;
    import java.awt.event.*;
    private SimpleFilteredTreeModel model;Altered TestFilteredTreeModel constructor as follows:
           JMenuBar bar = new JMenuBar();
            JMenu menu = new JMenu("Filters");
            JMenuItem item;
            item = new JMenuItem( "Data1Filter" );
            item.addActionListener( new ActionListener() {
                   public void actionPerformed( ActionEvent ev ) {
                        model.setViewFilter( new Data1Filter() );
              menu.add( item );
            item = new JMenuItem( "Data2Filter" );
            item.addActionListener( new ActionListener() {
                   public void actionPerformed( ActionEvent ev ) {
                        model.setViewFilter( new Data2Filter() );
              menu.add( item );
            item = new JMenuItem( "Data12Filter" );
            item.addActionListener( new ActionListener() {
                   public void actionPerformed( ActionEvent ev ) {
                        model.setViewFilter( new Data12Filter() );
              menu.add( item );
            bar.add( menu );
            f.setJMenuBar( bar );

  • A bug in the JTree(Missing some nodes)

    I have an application which implement a JTree & DnDTree. The left hand side is the original JTee, the right hand size is DnDTree which allows user to Drag and Drop some node from left JTree. The bug is: when I grag some node to right DnDTree, once I then click the left JTree, some nodes will be missing. I try my best for more than one week, but still couldn't fix it, could anybody take time to fina a way to fix it? The piece of code of creating JTree is as follow:
    /*public void createTestTree()
    DefaultMutableTreeNode rootRight = new DefaultMutableTreeNode("Root");
    DefaultMutableTreeNode root = createTreeModel();
    treeLeft = new DnDTree(root, true); //JTree(root, true);
    treeLeft.putClientProperty("JTree.lineStyle", "Angled");
    treeLeft.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    treeLeft.addTreeExpansionListener(new TreeExpansionListener(){
    public void treeCollapsed(TreeExpansionEvent e) {
    public void treeExpanded(TreeExpansionEvent e) {
    UpdateStatus updateThread;
    TreePath path = e.getPath();
    FileNode node = (FileNode)
    path.getLastPathComponent();
    if( ! node.isExplored()) {
    DefaultTreeModel model = (DefaultTreeModel)treeLeft.getModel();
    UpdateStatus us = new UpdateStatus();
    us.start();
    node.explore();
    model.nodeStructureChanged(node);
    class UpdateStatus extends Thread {
    public void run() {
    try { Thread.currentThread().sleep(450); }
    catch(InterruptedException e) { }
    SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    treeRight = new DnDTree(rootRight, true); treeRight.putClientProperty("JTree.lineStyle", "Angled");
    treeRight.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    treeRight.addTreeExpansionListener(new TreeExpansionListener(){
    public void treeCollapsed(TreeExpansionEvent e) {
    public void treeExpanded(TreeExpansionEvent e) {
    UpdateStatus updateThread;
    TreePath path = e.getPath();
    FileNode node = (FileNode)
                             path.getLastPathComponent();               
    if( ! node.isExplored()) {
    DefaultTreeModel model = (DefaultTreeModel)treeRight.getModel();
    UpdateStatus us = new UpdateStatus();
    us.start();
    node.explore();
    model.nodeStructureChanged(node);
    class UpdateStatus extends Thread {
    public void run() {
    try { Thread.currentThread().sleep(450); }
    catch(InterruptedException e) { }
    SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    My FileNode class is:
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.tree.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.io.File;
    import java.util.EventObject;
    public class GoodFileTree extends JPanel {
         public GoodFileTree() {
              final JTree tree = new JTree(createTreeModel());
              JScrollPane scrollPane = new JScrollPane(tree);
              this.add(scrollPane, BorderLayout.WEST);
              //getContentPane().add(scrollPane, BorderLayout.CENTER);
              this.add(GJApp.getStatusArea(),BorderLayout.SOUTH);
              //getContentPane().add(GJApp.getStatusArea(),BorderLayout.SOUTH);
              tree.addTreeExpansionListener(new TreeExpansionListener(){
                   public void treeCollapsed(TreeExpansionEvent e) {
                   public void treeExpanded(TreeExpansionEvent e) {
                        UpdateStatus updateThread;
                        TreePath path = e.getPath();
                        FileNode node = (FileNode)
                                            path.getLastPathComponent();
                        if( ! node.isExplored()) {
                             DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
                             GJApp.updateStatus("exploring ...");
                             UpdateStatus us = new UpdateStatus();
                             us.start();
                             node.explore();
                             model.nodeStructureChanged(node);
                   class UpdateStatus extends Thread {
                        public void run() {
                             try { Thread.currentThread().sleep(450); }
                             catch(InterruptedException e) { }
                             SwingUtilities.invokeLater(new Runnable() {
                                  public void run() {
                                       GJApp.updateStatus(" ");
         private DefaultMutableTreeNode createTreeModel() {
              /*File root = new File("E:/");
              FileNode rootNode = new FileNode(root);
              rootNode.explore();
              return new DefaultTreeModel(rootNode);*/
              DefaultMutableTreeNode top = new DefaultMutableTreeNode("Root");
              File[] fArr = File.listRoots();
              File fDrive;
              FileNode driveNode;
              for(int i=0; i<fArr.length; ++i)
                   fDrive = fArr;
                   driveNode = new FileNode(fDrive);
                   top.add(driveNode);
              return top;
         /*public static void main(String args[])
              try
                   UIManager.setLookAndFeel(
                   UIManager.getSystemLookAndFeelClassName()
                   //UIManager.getCrossPlatformLookAndFeelClassName()
              catch (Exception e)
              GJApp.launch(new GoodFileTree(),"JTree File Explorer",
                                            300,300,450,400);
    class FileNode extends DefaultMutableTreeNode {
         private boolean explored = false;
         public FileNode(File file)      {
              setUserObject(file);
         public boolean getAllowsChildren() { return isDirectory(); }
         public boolean isLeaf()      { return !isDirectory(); }
         public File getFile()          { return (File)getUserObject(); }
         public boolean isExplored() { return explored; }
         public boolean isDirectory() {
              File file = getFile();
              return file.isDirectory();
         public String toString() {
              File file = (File)getUserObject();
              String filename = file.toString();
              int index = filename.lastIndexOf(File.separator);
              return (index != -1 && index != filename.length()-1) ?
                                                 filename.substring(index+1) :
                                                 filename;
         public void explore() {
              if(!isDirectory())
                   return;
              if(!isExplored()) {
                   File file = getFile();
                   File[] children = file.listFiles();
                   for(int i=0; i < children.length; ++i)
                        add(new FileNode(children[i]));
                   explored = true;
    class GJApp extends WindowAdapter {
         static private JPanel statusArea = new JPanel();
         static private JLabel status = new JLabel(" ");
         public static void launch(final JFrame f, String title,
                                       final int x, final int y,
                                       final int w, int h) {
              f.setTitle(title);
              f.setBounds(x,y,w,h);
              f.setVisible(true);
              statusArea.setBorder(BorderFactory.createEtchedBorder());
              statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
              statusArea.add(status);
              status.setHorizontalAlignment(JLabel.LEFT);
              f.setDefaultCloseOperation(
                                       WindowConstants.DISPOSE_ON_CLOSE);
              f.addWindowListener(new WindowAdapter() {
                   public void windowClosed(WindowEvent e) {
                        System.exit(0);
         static public JPanel getStatusArea() {
              return statusArea;
         static public void updateStatus(String s) {
              status.setText(s);
    Thanks in advance.

    Hi Paul,
    sorry for my late reply, but I usually don't work on weekends (this time it was an exception).
    OK, then, to your problem:
    - at the first look I thought you did NOT follow all the instruction (namely, the constructor of your trees has no info that you want to use model, or whatsoever), but later I realized that your approach: create the tree first and then assign a model to it (or in fact, get the model from the tree via: tree.getModel()) might work as well
    - having no debugger I am not able to have much clue about your program / and it seems that you coding suffers from your being in a hurry:
    - no comments - don't know which method is expected to do what
    - misleading names (createTreeModel does nothing with the model, but creates some new nodes??)
    therefore, I'm sorry, but I'm not able to detect exactly where the error is.
    - anyway, having a quick glance on your code I have some suspections:
    - you have 2 trees (treeLeft, treeRight), but just one model (model)
    ( it seems that you assign it dynamically when needed - either you take the model of the left or of the right tree)
    - however, when this assignment takes place (in createTestTree()), you DO NOT ASSIGN IT to the class' protected attribute model, but to a local variable model (of the same type, however - since you introduce it as:
    DefaultTreeModel model you override the model from class' attributes) - therefore, your assignment is no valid when the block in which ot is located is finished
    - note, that you NEED the model when you add/delete nodes of the tree (somewhere in DnDTree? - then quite probably your local assignment of model is not valid any longer)
    My suggestion, therefore, is:
    somehow try to encapsulate the model to your tree (note that I only created the model outside the tree, because I needed it for running the constructor, but all other usages of the model are made WITHIN the class of the tree) - the best, do it the same way - through the constructor
    then, in the place when you insert/remove nodes you will have no problem at all
    I will e-mail you my whole "project" so that you may observe all parts - how it's written. I trust if you can't figure it out from my writings here (maybe I missed the point) you may get it from that example.
    Hope it helps - GOOD LUCK

Maybe you are looking for