1

我有一个处理一些数据的 GUI 应用程序,它将文本行转换为对象。创建的每个对象都显示在 JTextPane 或 JTextArea 上。例子:

第 1 行已创建 827401830 第 2 行已创建 827401831

因此,用户被告知该过程。

在幕后,有一个线程在后台运行并完成所有工作。问题是该线程的字段之一是 JTextArea。它看起来像这样:

public class ConsumerThread implements Runnable 
{
    private ArrayBlockingQueue<TicketExchangeLine> queue;
    private JTextArea textArea; 

public ExchConsumerThread(ArrayBlockingQueue<TicketExchangeLine> queue, JTextArea textArea) 
{
    this.queue = queue;
    this.textArea = textArea; 
}

public void run() 
{
    try
    {       
        while (true)
        {               
            // check if end of file from producer POV
            if (queue.peek()!=null && ...)
                break;

            MyObject obj = queue.take();

            try{
                //do the process here
                textArea.append("here comes the output for the user..."+obj.getID);

            }catch(Exception nfe)
            {
                //Oops  
            } 
        }

        textArea.append("\nDone!");

    }catch (InterruptedException e)
    {
        // Oops
    }catch(Exception exp)
    {
        exp.printStackTrace();
    }
}

}

所以上面的代码可以正常工作,但有时我不是从 GUI 使用这个线程,然后我无缘无故地实例化一个 JTextArea;更糟糕的是,我必须 system.out 一切才能看到进程。

问题:如何在不使用线程中的 Swing 组件的情况下将所有“处理过的数据”记录到 JTextArea(或有时是 JTextPane)?

谢谢!

4

4 回答 4

2

不是传递 a JTextArea,而是传递一个OutputStream(例如 a PrintStream)作为参数。这提供了足够的灵活性:

  • 您的线程只是写入输出流
  • 如果您希望输出出现在 aJTextArea中,则传递一个输出流,它将输出附加到 aJTextArea中。对文本区域的写入应该发生在 EDT 上,但是输出流会处理这个问题。您的线程不知道这一点
  • 如果要将输出通过管道传输到System.out,只需将System.out直接作为参数传递
于 2012-05-04T13:40:19.590 回答
1

大多数 Swing 图形组件都分为图形表示(视图)和显示数据的抽象表示(模型)。JTextArea并且JTextPane是使用Document实例作为其模型的图形组件。

因此,您可以引用 Document 并调用 ,而不是引用和JTextArea调用。然后,如果您需要实例化 JTextArea,请使用 JTextArea 的构造函数,该构造函数将 Document 作为参数(或使用其方法)。textArea.appenddocument.insertStringsetDocument

此外,Swing 不是线程安全的,每个可能影响 Swing 组件的方法调用都应该发生在 EDT(AWT 的调度线程)中。要在 EDT 上注入一些代码,请使用SwingUtilities.invokeLater.

于 2012-05-04T13:40:26.593 回答
0

不确定这是否是您要实现的目标,但使用您当前的代码,您可以像这样更改EDT上的 JTextArea :

final MyObject obj = queue.take();
try {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            textArea.append("here comes the output for the user..." + obj.getID);
        }
    });
}
于 2012-05-04T13:31:12.960 回答
0

您似乎已经找到了答案,但我认为这是解决您问题的优雅而灵活的解决方案:

从不同的地方向摇摆 JTextArea 发送消息

于 2012-09-11T07:54:56.747 回答