如何防止水平滚动条在JTree.scrollPathToVisible(TreePath)上滚动?

时间:2014-01-29 13:27:59

标签: java swing jscrollpane jtree

虽然将树路径滚动到可见是很容易实现的,但我想知道我是否也可以滚动到路径而不会干扰水平滚动条的状态或重置它的值,而不会闪烁。

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);
            }
        });
    }

}

以上示例演示了我想要做的事情。单击该按钮后,程序将滚动到具有长名称的节点。出于某种原因,它试图将尽可能多的节点标签放入其视图中,从而导致水平滚动条滚动。我通过scroll.getHorizontalScrollBar().setValue(0)“修复”了这一事实,这会引入不必要的闪烁。我想完全避免它。有没有办法做到这一点?

这不是一个javascript问题。

1 个答案:

答案 0 :(得分:2)

JTree.scrollPathToVisible旨在滚动使路径进入视图所需的最小量,因此可能需要使用此默认行为。但是,假设您有保持水平滚动不变的特定需求,您可以实现自己的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);
        }
    }
}

这只是默认实现的副本,附加行将bounds.x设置为0。