2012-09-24 50 views
1

我在编写JScrollPane来设置可滚动的JPanel,其中包含JTextPaneJTable把JScrollPane滚动条的栏放在XXX处,不要“闪烁”

当我加载框架时,我用一个非常长的文本初始化JTextPane,然后滚动条向下移动直到文档结束。

我想让这个滚动条位于文档的顶部。所以我把我的滚动条的值设置为0,则文字加载后:

SwingUtilities.invokeLater(new Runnable() { 
    @Override 
    public void run() { 
     myScrollPane.getVerticalScrollBar().setValue(0); 
    } 
}); 

它正常工作(即我顶得上的滚动条),但呈现的行为是很丑陋。现在它加载文本,显示结束(滚动条在文本窗格的底部),然后立即(几毫秒,但仍然可见)向上移动以获得顶部的滚动条。由此产生的效果是用户的“闪光”,这是非常不愉快的。每次重新加载整个文档时,我都有同样的问题。

我怎么能避免这种情况?

谢谢。

+0

直到将滚动条设置为零后,才设置frame.setVisible(true)? –

+0

但是,如果我的所有组件都已经实例化并且只想“重新加载”整个文档,则它不起作用。例如:所有框架都是可见的,我点击一个JButton,用“HELLO”代替所有的“hello”单词(在文档中)。该文档在我的文本窗格中重新编写,但滚动条再次位于其底部。 :/ 谢谢你们。 –

+1

另请参阅此[备选](http://stackoverflow.com/a/11299764/230513)。 – trashgod

回答

2

最后,我把默认插入NEVER_UPDATE

JTextPane textPane = new JTextPane(); 
DefaultCaret caret = (DefaultCaret) textPane.getCaret(); 
caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE); 

HeresetUpdatePolicy()的文档。然后我自己更新脱字符号。

+0

不错,不知道。谢谢你的提示! –

2

在更新其内容之后但在创建JScrollPane之前,您可以简单地将JTextPane中的插入符号位置设置为0。这会迫使JScrollPane立即显示文本的开始而不会无意中向后滚动。

就做这样的事情:

JTextPane textPane = new JTextPane(); 
textPane.setText ("Some long text here..."); 
textPane.setCaretPosition (0); 

JScrollPane scrollPane = new JScrollPane (textPane); 

如果你已经有文字 - 只是做了更新和插入位置开关一起在美国东部时间:

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。

+0

在这里看到我的评论:http://stackoverflow.com/questions/12567668/put-the-bar-of-a-jscrollpane-scroll-bar-at-xxx-without-flashing/12568063#comment16931693_12567668 –

+0

@MarcdeVerdelhan你应该在EDT中一个接一个地设置textpane内容和插入位置,在这种情况下,只有在设置了插入符号位置后,才会更新窗格。看我的答案中的例子。 –

+0

感谢你和@trashgod,我更好地理解EDT中的插入符号是如何管理的(使用'adjustVisibility()'等)。我选择了@trashgod给出的[另类](http://stackoverflow.com/a/11299764/230513),但你的方式也能正常工作。感谢你们。 –