Search code examples
javaswingjscrollpaneviewportjtree

Set viewport at the end of the JTree on inserting a new node


I have a JTree which is in a JScrollPane. I would like to update the viewport and set it to the end of the JTree upon inserting a new node.

I want to do something similar to this...

   scrollPane = new JScrollPane( textPane ));
   scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

   DefaultCaret caret = (DefaultCaret) textPane.getCaret();
   caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);

but with JTree not JTextPane. The JTree class does not have a getCaret() method, so I have checked the JTree API but could not find what I need. Is there an easy way to get this working?


Solution

  • You can get the JViewport of the scroll pane, and use JViewPort#scrollRectToVisible(Rectangle contentRect). Something like

    int y = tree.getPreferredSize().height;
    pane.getViewport().scrollRectToVisible(new Rectangle(0, y, 0, 0));
    

    Here's a full example

    import java.awt.Rectangle;
    import javax.swing.*;
    import javax.swing.tree.DefaultMutableTreeNode;
    
    public class TestViewPort {
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable(){
                public void run() {
                    DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
                    for (int i = 0; i < 100; i++) {
                        root.add(new DefaultMutableTreeNode(Integer.toString(i)));
                    }
                    JTree tree = new JTree(root);
                    tree.setVisibleRowCount(10);
                    JScrollPane pane = new JScrollPane();
                    pane.setViewportView(tree);
                    int y = tree.getPreferredSize().height;
                    pane.getViewport().scrollRectToVisible(new Rectangle(0, y, 0, 0));
                    JOptionPane.showMessageDialog(null, pane);
                }  
            });
        }
    }
    

    • Or simply as AndrewThompson pointed out tree.scrollRectToVisible(new Rectangle(0, y, 0, 0));, as JTree also has this method.

    UPDATE: probably best solution