2

我有一个包含垂直框的 JScrollPane。我在 Box 顶部插入新的 JPanel。如果我使用滚动条向下滚动,我希望当前视图保持在我向下滚动到的位置。例如,如果我在框中有 50 个面板并使用滚动条查看面板 20,我希望视图保留在框 20 上,即使顶部添加了其他框。此外,如果我使用滚动条向上滚动到顶部,我希望视图在添加新面板时显示它们。知道怎么做吗?

顺便说一句,没有必要使用 JScrollPane 或 Box。示例代码只是为了帮助解释我正在尝试做的事情。

示例代码:

导入 java.awt.*;
导入 java.awt.event.*;
导入 javax.swing.*;

公共类 TestScrollPane 扩展 JFrame {

    JScrollPane 滚动窗格;
    盒子盒子;
    私有静态int panelCount = 0;

    公共TestScrollPane(){
        setPreferredSize(新维度(200, 400));
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        scrollPane = 新的 JScrollPane();
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_​​ALWAYS);
        scrollPane.getVerticalScrollBar().setUnitIncrement(15);
        box = Box.createVerticalBox();
        scrollPane.getViewport().add(box);

        this.add(scrollPane);
        这个.pack();
        this.setLocationRelativeTo(null);
        this.setVisible(true);

        定时器 t = new Timer(500, new ActionListener() {

            公共无效actionPerformed(ActionEvent ae){
                box.add(new TestPanel(), 0);
                scrollPane.validate();
            }
        });
        t.setRepeats(true);
        t.start();
    }

    公共类 TestPanel 扩展 JPanel {

        int myId = panelCount++;

        公共测试面板(){
            this.setLayout(new GridBagLayout());
            this.setBorder(BorderFactory.createBevelBorder(1));
            JLabel 标签 = new JLabel("" + myId);
            label.setHorizo​​ntalAlignment(JLabel.CENTER);
            label.setVerticalAlignment(JLabel.CENTER);

            this.setMaximumSize(新维度(100, 100));
            this.setPreferredSize(新维度(100, 100));

            this.add(标签);
        }
    }

    公共静态无效主要(字符串[]参数){
        java.awt.EventQueue.invokeLater(new Runnable() {

            公共无效运行(){
                TestScrollPane testScrollPane = new TestScrollPane();
            }
        });
    }
}

编辑:这就是我最终更改代码的方式。没有看到明显的东西,我觉得有点愚蠢。无论如何,感谢那些帮助过的人。

            公共无效actionPerformed(ActionEvent ae){
                点视图 = scrollPane.getViewport().getViewPosition();
                TestPanel 面板 = 新的 TestPanel();
                box.add(面板, 0);
                scrollPane.validate();
                如果(view.y!= 0){
                    view.y += panel.getHeight();
                    scrollPane.getViewport().setViewPosition(view);
                }
            }

顺便说一句,我已将此问题交叉发布到http://www.coderanch.com/t/528829/GUI/java/JScrollPane-adding-JPanels-at-top#2398276仅供参考,供那些可能关心的人使用。

4

2 回答 2

0

就像是:

    Timer t = new Timer(1000, new ActionListener() {

        public void actionPerformed(ActionEvent ae) {
            TestPanel panel = new TestPanel();
            box.add(panel, 0);
            JViewport vp = scrollPane.getViewport();
            Point p = vp.getViewPosition();
            p.y += panel.getPreferredSize().height;
            scrollPane.revalidate();
            vp.setViewPosition(p);
        }
    });
于 2011-02-27T16:12:56.307 回答
0

您可以获得要使其可见的组件的边界(使用 JComponent 的 getBounds 方法),并将其用作 JViewPort 的 scrollRectToVisible 方法的输入。

于 2011-02-27T11:06:22.117 回答