Search code examples
javaswingjtreedefaulttablemodel

JTree update nodes without collapsing


I have a Java SE 7 application that needs to have the JTree nodes updated. From the tutorial given by Oracle using this thread, there's no given hint on how I could update the label (displayed text of the node on the Tree) on code. Currently I am using DefaultTreeModel as the model of my JTree and DefaultMutableTreeNode as the nodes of the said Tree.

To further detail about the application I am working on, I am developing a chat facility having the contact(s) displayed with their availability status (whether Online, Offline, etc.) per account.

The question is, how can I update the displayed text of a particular node without (at most) removing it from it's parent and adding it on it's designated index. Like a DefaultMutableTreeNode.setText("<new label>")?


UPDATE : January 20, 2013

Redefined the question for clarifications.


Solution

  • May this simple and executable program help you to resolve your issue.

    public class JTreeDemo  extends JPanel
        implements Runnable {
    
    private JTree tree;
    private DefaultTreeModel treeModel ;
    private Random rnd = new Random();
    private List<User> userList;
    public JTreeDemo() {
        super( );
    
        //Create the nodes.
        DefaultMutableTreeNode top =
            new DefaultMutableTreeNode("Users");
        treeModel = new DefaultTreeModel(top);
        createNodes(top);
    
        //Create a tree that allows one selection at a time.
        tree = new JTree(treeModel);
        tree.getSelectionModel().setSelectionMode
                (TreeSelectionModel.SINGLE_TREE_SELECTION);
    
        //Create the scroll pane and add the tree to it. 
        JScrollPane treeView = new JScrollPane(tree);
    
    
        //Add the split pane to this panel.
        add(treeView);
    }
    
    public String getRandomStatus() {
        int nextInt = rnd.nextInt(100);
        if( nextInt%2==0) {
            return "Online";
        } else {
            return "Offline";
        }
    }
    @Override
    public void run() {
         while(true) {
            try {   
              Thread.sleep(1000);
              int nextInt = rnd.nextInt(10);
              User user = userList.get(nextInt);
              user.setStatus(getRandomStatus());
              treeModel.nodeChanged(user);
            } catch (InterruptedException ex) {
                // handle it if necessary
            }
         }
    }
    
    private class User extends DefaultMutableTreeNode {
        public String userName;
        public String status;
    
        public User(String name) {
            userName = name;
    
        }
    
        public void setStatus(String status) {
            this.status = status;
        }
    
        public String getStatus() {
            return status;
        }
    
        @Override
        public String toString() {
            String color = status.equals("Online") ? "Green" : "Red";
            return "<html><b color='"+color+"'>"+
                    userName +"-"+status +"</b></html>";
        }
    
    }
    
    
    private void createNodes(DefaultMutableTreeNode top) {
        userList = new ArrayList() ;
        for(int i=0;i<10;i++) {
            User u1 = new User("User " + (i+1));
            u1.setStatus("Online");
             top.add(u1);
             userList.add(u1);
        }
    }
    
    private static void createAndShowGUI() {
    
        JFrame frame = new JFrame("TreeDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //Add content to the window.
        JTreeDemo jTreeDemo = new JTreeDemo();
        frame.add(jTreeDemo);
        frame.pack();
        frame.setVisible(true);
        // update status randomly
        Thread thread = new Thread(jTreeDemo);
        thread.start();
    }
    
     public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
     }
    }
    

    I've added a Thread to update Status randomly, hope you can modify base on your need.

    Output :
    enter image description here


    Edit:
    1. Based on suggestion I've removed reload(node) and added tree model reload.