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

Java 避免在JScrollPane中调用setViewportView后自动滚动到底部,java,swing,jscrollpane,Java,Swing,Jscrollpane,情况: 我有一个JScrollPane“滚动窗格”,其中包含一个JPanel“主面板”,其中包含多个JPanels“itempanel”,一个在另一个之下(从数据库读取的信息和相应创建的对象)。 用户可以在现有条目之间插入新条目。在这种情况下,新条目将添加到数据库中,所有组件(“ItemPanel”)将再次生成并添加到新的“mainPanel”。 最后,使用setViewPortView将新的“主面板”设置为滚动窗格 Vector<JPanel> itemPanels = gener

情况: 我有一个
JScrollPane
“滚动窗格”,其中包含一个
JPanel
“主面板”,其中包含多个
JPanel
s“itempanel”,一个在另一个之下(从数据库读取的信息和相应创建的对象)。 用户可以在现有条目之间插入新条目。在这种情况下,新条目将添加到数据库中,所有组件(“ItemPanel”)将再次生成并添加到新的“mainPanel”。 最后,使用setViewPortView将新的“主面板”设置为滚动窗格

Vector<JPanel> itemPanels = generateMyPanelsFromDB();
JPanel mainPanel = new JPanel(new GridBagLayout());
//.. layout stuff
for(JPanel itemPanel: itemPanels) mainPanel.add(itemPanel,<gridbagconstraintsvar>);
scrollPane.setViewportView(mainPanel);
这没有任何作用(scrollpane仍然滚动到最后,没有更多的事情发生)。 我只使用下面的嵌套调用器重新回滚,但这不是正确的方法,也不能阻止向下滚动然后再向上滚动(=伤眼睛)

新增2012-01-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);
    }
}
public类DebugImportCommandEditPanel扩展JPanel{
私有静态最终长serialVersionUID=1L;
私有JScrollPane命令滚动窗格;
公共调试导入命令编辑面板(){
此.setLayout(新的BorderLayout());
this.commandScrollPane=newJScrollPane(this.getMainPanel());
this.add(this.commandScrollPane,BorderLayout.CENTER);
}
私有JPanel getMainPanel(){
Vector innerPanels=新向量();

对于(int i=0;i看到您的编辑:它可能是嵌套的JTextPane-出乎意料地(对我来说,至少:-),它似乎是行为,即使不是视口的直接子对象

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

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 "+
    ....

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

afair,默认行为会使其不滚动到底部-因此代码中的某些内容会使其偏离默认值。要跟踪它,请显示一个具有您描述的行为的SSCCE。同意a.m.注释,以获得更好的帮助,请尽快发布一个简短的可运行的.compileable,大约是
JFrame
,使用main
JPanel
(使用嵌套的空
JPanel
==hardcode
PreferredSize
),我确实做了一个SSCCE(不知道它代表什么,但我想你说的是一个简化的示例程序来证明效果)我可以确认没有自动滚动到结尾。我必须进一步研究它,并将使用outcomming.Thanx还原到目前为止!非常奇怪。如果我添加我的测试面板(调用setViewportView后不会自动滚动到结尾)对于我的实际程序,它最初也会向下滚动,尽管它是使用同一个layoutmanager添加的,并且没有调用其他例程。不知道是什么导致了这种情况。
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 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 "+
    ....