java - 在 JScrollPane 中调用 setViewportView 后避免自动滚动到底部

标签 java swing jscrollpane

情况: 我有一个JScrollPane“scrollPane”,其中包含一个JPanel“mainPanel”,其中包含多个JPanels“itemPanels”,一个在下一个(从数据库读取的信息和相应创建的对象)。 用户可以在现有条目之间插入新条目。在这种情况下,新条目将添加到数据库中,并且所有组件(“itemPanel”)将再次生成并添加到新的“mainPanel”中。 最后,新的“mainPanel”被设置为带有setViewPortView 的scrollPane。

Vector<JPanel> itemPanels = generateMyPanelsFromDB();
JPanel mainPanel = new JPanel(new GridBagLayout());
//.. layout stuff
for(JPanel itemPanel: itemPanels) mainPanel.add(itemPanel,<gridbagconstraintsvar>);
scrollPane.setViewportView(mainPanel);

发生的情况是新组件被正确添加,并且滚动 Pane 自动滚动到末尾。

我怎样才能避免滚动 Pane 滚动到最后(=停留在之前的位置)。 我尝试过:将上述操作包围起来:

int currentPos = scrollPane.getVerticalScrollBar().getValue();
//.. to the setViewPortView stuff
scrollPane.getVerticalScrollBar().setValue(value);

这不会执行任何操作(滚动 Pane 仍然滚动到末尾,并且没有发生更多事情)。 我只能使用以下嵌套 invokeLater 重新滚动回来,但这不是正确的方法,也不会阻止向下滚动然后向上滚动(=伤害眼睛)

final int value = scrollPane.getVerticalScrollBar().getValue();
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
       public void run() { 
            scrollPane.setViewportView(mainPanel);
            Thread t = new Thread() {
                public void run() {
                    try {
                        Thread.sleep(1);
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    javax.swing.SwingUtilities.invokeLater(new Runnable() {
                           public void run() { 
                                scrollPane.getVerticalScrollBar().setValue(value);
                           }
                        });
                }
            };
            t.start();
       }
    });

添加于 2012 年 1 月 14 日:

public class DebugImportCommandEditPanel extends JPanel {
private static final long serialVersionUID = 1L;

private JScrollPane commandScrollPane;

public DebugImportCommandEditPanel() {
    this.setLayout(new BorderLayout());
    this.commandScrollPane = new JScrollPane(this.getMainPanel());
    this.add(this.commandScrollPane, BorderLayout.CENTER);
}

private JPanel getMainPanel() {
    Vector<InnerPanel> innerPanels = new Vector<InnerPanel>();
    for(int i=0;i<12;i++) innerPanels.add(new InnerPanel((i+1)+ "."));

    JPanel mainPanel = new JPanel(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();
    c.gridx=0;c.gridy=0;c.weightx=1;c.weighty=1;c.fill = GridBagConstraints.BOTH;
    for(InnerPanel panel: innerPanels) {
        mainPanel.add(panel,c);
        c.gridy++;
    }
    return mainPanel;
}

class InnerPanel extends JPanel {
    private static final long serialVersionUID = 1L;

    protected InnerPanel(String number) {
        this.setLayout(new BorderLayout());
        this.setBorder(BorderFactory.createTitledBorder("Inner Panel No. "+number));
        JTextPane textPane = new JTextPane();
        textPane.setText("Lorem ipsum dolor sit amet consectetuer tellus sociis sapien porttitor "+
                        "Suspendisse. Mattis morbi eu In non ante convallis\n  "+
                        "tempus risus venenatis urna. Sed ipsum et parturient volutpat\n "+ 
                        "adipiscing dolor quis adipiscing Donec odio.\n "+
                        "Neque adipiscing pretium lacus Phasellus neque a vel sed wisi alique\n"+
                        "t. Condimentum Sed pretium libero vitae facilisi pretium sit consequat a "+ 
                        "tincidunt. Pharetra ac Aliquam.");
        this.add(textPane,BorderLayout.CENTER);
    }
}

}

最佳答案

看到您的编辑:它可能是嵌套的 JTextPane - 出乎意料(对我来说,至少:-),似乎 affect the overall scrolling即使不是视口(viewport)的直接子级行为。

解决方法是将插入符策略配置为在设置文本时不更新:

JTextPane tp = new JTextPane();
DefaultCaret caret = (DefaultCaret) tp.getCaret();
caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
textPane.setText("Lorem ipsum dolor sit amet consectetuer tellus sociis sapien porttitor "+
    ....

请注意,您必须在设置文本之前设置策略。

关于java - 在 JScrollPane 中调用 setViewportView 后避免自动滚动到底部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14280660/

相关文章:

java - JScrollPane - 平滑滚动

java - 如何在java中为堆编写递归trickleUp方法?

java - 即使绘制新文本,也设置一次 swing 应用程序的默认字体

java - 如何使用拖放交换 GridLayout 中排列的按钮上的图标?

java - 清除一个 JTable 中的数据也会删除另一个 JTable

javascript - jscrollpane垂直滚动条

java - 以递归方式将列表的元素与以下元素进行比较

java - 从现有 Java 项目创建 servlet

java - 终结符和非终结符

java - 如何在固定位置上绘制JPanel?