我在某个地方有几千行代码,我注意到当我更新太多时我的 JTextPane 会闪烁。我在这里写了一个简化版本:

import java.awt.*;
import javax.swing.*;

public class Test
{
    static JFrame f;
    static JTextPane a;
    static final String NL = "\n";

    public static void main(String... args)
    {
        EventQueue.invokeLater(new Runnable(){
        public void run()
        {
        f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
        f.setSize(400, 300);
        f.setLocationRelativeTo(null);

        a = new JTextPane();
        f.add(new JScrollPane(a));

        new Thread(new Runnable(){
            public void run()
            {
                int i = 0;
                StringBuffer b = new StringBuffer();
                while(true)
                {
                    b.append(++i+NL);
                    a.setText(b.toString());
                    a.setCaretPosition(b.length());
                    try{Thread.sleep(10);}catch(Exception e){}
                }
            }
        }).start();
        }
        });

    }
}

这是针对终端 (cmd) 风格的 GUI 组件——

我想我已经在这里做了所有我能做的优化,包括 \n 作为最终变量,因此它不会被构造数百次。尽管如此,闪烁仍然是明显且不可接受的。几分钟后,该组件完全冻结。我必须非常快速地更新组件,并且更新时窗格必须滚动到底部。

我一直在考虑从头开始制作我自己的 JTextPane 版本,但我想看看你们是否有更简单的解决方案。

有帮助吗?

解决方案

您的部分错误是您正在从事件线程外部访问 Swing 组件!是的, 设置文本() 是线程安全的,但 Swing 方法不是线程安全的,除非明确声明它们。因此, 设置插入符位置() 不是线程安全的,必须从事件线程访问。这几乎肯定是您的应用程序最终冻结的原因。

笔记: JTextPane 继承其 setText() 方法来自 JEditorPane 和它的 setCaretPosition 方法来自 JTextComponent, ,这解释了上一段中的链接不会转到 JTextPane JavaDoc 页面。

为了线程安全,你至少需要调用 setCaretPosition() 从事件线程中,您可以使用如下代码来执行此操作:

SwingUtilities.invokeAndWait(new Runnable() {
  public void run() {
    a.setText(b.toString());
    a.setCaretPosition(b.length());
  }
}

既然你必须打电话 setCaretPosition() 从事件线程中,您也可以调用 setText() 来自同一个地方。

您可能不需要手动设置插入符位置。查看 JavaDoc 中的“插入符更改”部分 JText组件.

最后,您可能想查看由两篇文章组成的系列:

其他提示

不知道这是否会工作,但你可以尝试使用文本窗格的insertString()实例的Document方法。我会尝试有在文档的最后一个空格,并保持定位该空间后,插入符号;但是当你插入一个字符串,空格前插入。这样的插入位置将保持在自动文档的末尾。

我在想,该文本窗格中可能会得到重新绘制了两次,一次是当你调用setText()而一旦当你调用setCaretPosition(),以及可能有助于闪烁。不知道,虽然(它已经有一段时间,因为我与Swing合作)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top