情况:
我有一个JScrollPane
“scrollPane”,其中包含JPanel
“mainPanel”,其中包含多个JPanel
个“itemPanel”,彼此相同(从数据库中读取信息并相应地创建对象)。
用户可以在现有条目之间插入新条目。在这种情况下,新条目将添加到数据库中,并再次生成所有组件(“itemPanel”)并将其添加到新的“mainPanel”中。
最后,使用setViewPortView将新的“mainPanel”设置为scrollPane。
Vector<JPanel> itemPanels = generateMyPanelsFromDB();
JPanel mainPanel = new JPanel(new GridBagLayout());
//.. layout stuff
for(JPanel itemPanel: itemPanels) mainPanel.add(itemPanel,<gridbagconstraintsvar>);
scrollPane.setViewportView(mainPanel);
如果正确添加了新组件,滚动窗格会自动滚动到最后。
我怎样才能避免,滚动窗格滚动到最后(=保持原样)。 我尝试了什么:围绕上述行动:
int currentPos = scrollPane.getVerticalScrollBar().getValue();
//.. to the setViewPortView stuff
scrollPane.getVerticalScrollBar().setValue(value);
这没有做任何事情(滚动窗格仍然滚动到最后,没有更多的事情发生)。 我只是设法使用以下嵌套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-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);
}
}
}
答案 0 :(得分:1)
看到你的编辑:它可能是嵌套的JTextPane - 意外地(对我来说,至少:-),即使不是视口的直接子节点,它似乎也是affect the overall scrolling行为。
解决方法是将插入符号策略配置为在设置文本时不更新:
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 "+
....
请注意,您必须在设置文本之前设置策略。