JScrollPane 在顶部添加 JPanel 并保持当前滚动视图

Posted

技术标签:

【中文标题】JScrollPane 在顶部添加 JPanel 并保持当前滚动视图【英文标题】:JScrollPane adding JPanels at the top and keeping current scroll view 【发布时间】:2011-07-05 04:54:58 【问题描述】:

我有一个包含垂直框的 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 仅供参考,供那些可能关心的人参考。

【问题讨论】:

我为您提供了用于解决问题的代码的想法,并且您为解决方案赢得了荣誉。下次遇到问题时,祝您好运。 @camickr 您是否想为 JB Nizet 的解决方案赢得荣誉?无论如何,直到我已经根据 JB 的想法编写了代码,我才阅读您的帖子。我想你迟到了几个小时的聚会。往下读。不过还是谢谢。 我的解决方案在您编辑的解决方案前三小时发布。我还没有看到其他人发布的解决方案。 【参考方案1】:

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

【讨论】:

这是可能的,但它会导致视图跳转到面板。我希望视图与用户向下滚动时看到的完全相同。 您可以在添加面板之前在视口上调用 getViewRect(),通过添加新添加的面板的高度将获得的矩形平移到底部,然后 scrollRectToVisible 返回到视口在面板添加之前。 是的,很简单,事后看来答案很明显。谢谢,非常感谢。【参考方案2】:

类似:

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

【讨论】:

以上是关于JScrollPane 在顶部添加 JPanel 并保持当前滚动视图的主要内容,如果未能解决你的问题,请参考以下文章

Java GUI:将JPanel添加进JScrollPane

java swing JPanel添加在JScrollPane上,有垂直的滚动条,可是滚动条拉到底,只显示了JPanel的一部分。

动态创建 jCheckBox 并添加到 jScrollPane

如何做到这一点,以便当我将可动态调整大小的 JPanel 放入 JScrollPane 时它​​可以工作?

包含 JPanel 的 JScrollPane 不会滚动

JScrollPane 上面放 JPanel 怎么让 JScrollPane 在适当的时候显示滚动条