我正在构建JScrollPane
以设置可滚动的JPanel
,其中包含JTextPane
和JTable
。
当我加载框架时,我使用非常长的文本初始化JTextPane
,然后滚动条向下移动直到文档的末尾。
我想把这个滚动条放在文档的顶部。所以我在文本加载后将滚动条的值设置为0:
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
myScrollPane.getVerticalScrollBar().setValue(0);
}
});
它工作正常(即我将滚动条放在顶部)但渲染的行为非常难看。现在它加载文本,显示结束(文本窗格底部的滚动条),然后立即(几毫秒,但仍然可见)向上移动以使滚动条在顶部。产生的效果对于用户来说是“闪光”,这是非常不愉快的。每次重新加载整个文档时都会遇到同样的问题。
我怎么能避免这种情况?
感谢。
答案 0 :(得分:2)
您可以在更新内容后但在创建JTextPane
之前,将JScrollPane
中的插入符号位置设置为0。这将迫使JScrollPane
立即显示文本的开头而不会毫无意义地向后滚动。
做这样的事情:
JTextPane textPane = new JTextPane ();
textPane.setText ( "Some long text here..." );
textPane.setCaretPosition ( 0 );
JScrollPane scrollPane = new JScrollPane ( textPane );
如果您已有文本 - 只需在EDT中执行更新和插入位置切换:
public static void main ( String[] args ) throws InterruptedException
{
final JFrame frame = new JFrame ();
final JTextPane textPane = new JTextPane ();
frame.add ( new JScrollPane ( textPane ) );
frame.setSize ( 400, 300 );
frame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
frame.setLocationRelativeTo ( null );
frame.setVisible ( true );
Thread.sleep ( 2000 );
SwingUtilities.invokeLater ( new Runnable ()
{
public void run ()
{
textPane.setText ( "line\nline\nline\nline\nline\nline\nline\nline" +
"\nline\nline\nline\nline\nline\nline\nline\nline\nline" +
"\nline\nline\nline\nline\nline\nline\nline\nline\nline" +
"\nline\nline\nline\nline\nline\nline\nline\nline\nline" );
textPane.setCaretPosition ( 0 );
}
} );
Thread.sleep ( 2000 );
SwingUtilities.invokeLater ( new Runnable ()
{
public void run ()
{
textPane.setText ( "line2\nline\nline\nline\nline\nline\nline\nline" +
"\nline\nline\nline\nline\nline\nline\nline\nline\nline" +
"\nline\nline\nline\nline\nline\nline\nline\nline\nline" +
"\nline\nline\nline\nline\nline\nline\nline\nline\nline" );
textPane.setCaretPosition ( 0 );
}
} );
}
但我同意这不是最好的解决方案。我想当文本内容发生变化时,没有简单的方法可以强制将textpane插入符号设为0。
答案 1 :(得分:2)
最后我将默认插入符号放到NEVER_UPDATE
。
JTextPane textPane = new JTextPane();
DefaultCaret caret = (DefaultCaret) textPane.getCaret();
caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
Here是setUpdatePolicy()
的文档。然后我自己更新插入符号。