How to prevent horizontal scroll bar from scrolling on JTree.scrollPathToVisible(TreePath)?

StackOverflow https://stackoverflow.com/questions/21432517

  •  04-10-2022
  •  | 
  •  

문제

While scrolling a tree path to visible is trivial to implement, I'm wondering if I can also scroll to a path without disturbing the state of the horizontal scroll bar or by reseting it's value, without flickering.

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

public class TreeScroll extends JFrame {

    private JScrollPane scroll;
    private JTree tree;
    private DefaultTreeModel model;
    private JButton button;

    public TreeScroll() {
        setLayout(new BorderLayout());

        DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
        root.add(new DefaultMutableTreeNode("filler"));
        root.add(new DefaultMutableTreeNode("filler"));
        root.add(new DefaultMutableTreeNode("filler"));
        root.add(new DefaultMutableTreeNode("filler"));
        root.add(new DefaultMutableTreeNode("filler"));
        root.add(new DefaultMutableTreeNode("filler"));
        root.add(new DefaultMutableTreeNode("filler"));
        root.add(new DefaultMutableTreeNode("filler"));
        root.add(new DefaultMutableTreeNode("filler"));
        root.add(new DefaultMutableTreeNode("filler"));
        root.add(new DefaultMutableTreeNode("filler"));
        root.add(new DefaultMutableTreeNode("filler"));
        final DefaultMutableTreeNode longNode = 
                new DefaultMutableTreeNode("long text node is long");
        root.add(longNode);
        model = new DefaultTreeModel(root);

        tree = new JTree(model);
        scroll = new JScrollPane(tree);
        add(scroll);

        button = new JButton("Scroll");
        add(button, BorderLayout.PAGE_END);
        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                TreeNode[] pathToRoot = model.getPathToRoot(longNode);
                TreePath treePath = new TreePath(pathToRoot);
                tree.setSelectionPath(treePath);
                tree.scrollPathToVisible(treePath);
                scroll.getHorizontalScrollBar().setValue(0);
            }
        });

        setSize(50, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                new TreeScroll().setVisible(true);
            }
        });
    }

}

The above example demonstrates what I want to do. Upon clicking the button, the program scrolls to a node with a long name. For some reason it tries to fit as much of the node label as it possibly can into it's view, which results in horizontal scroll bar scrolling. I "fix" that after the fact via scroll.getHorizontalScrollBar().setValue(0), which introduces an unwanted flicker. I'd like to prevent it entirely. Is there a way of doing that?

This is not a javascript question.

도움이 되었습니까?

해결책

JTree.scrollPathToVisible is designed to scroll the minimum amount necessary to bring the path into view, so it is probably desirable to use this default behavior. However, assuming you have specific needs to keep the horizontal scrolling constant, you could implement your own version of scrollPathToVisible:

private void scrollPathToVisible(TreePath treePath) {
    if (treePath != null) {
        tree.makeVisible(treePath);

        Rectangle bounds = tree.getPathBounds(treePath);

        if (bounds != null) {
            bounds.x = 0;
            tree.scrollRectToVisible(bounds);
        }
    }
}

This is simply a copy of the default implementation with the additional line to set bounds.x to 0.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top