Java:BufferedStreams和事件处理程序



我正在使用JTextArea的"控制台"上工作,一切都很好,只是我的输出没有像我希望的那样工作。

我使用的是我在Stackoverflow上找到的一个类的修改版本。

import java.io.*;
import javax.swing.*;
public class textareaStream extends OutputStream {
//*************************
//* Parameters
//*************************
private JTextArea textArea; // target text area
private byte[] aByte;     // array for write(int val);
//*************************
//* Constructor
//*************************
public textareaStream(JTextArea ta) {
    textArea=ta;
    aByte=new byte[1];
}

//*************************
//* Writing methods
//*************************
public void write(int val) {
    aByte[0]=(byte)val;
    write(aByte,0,1);
}
public void write(byte[] ba) {
    write(ba,0,ba.length);
}
public synchronized void write(byte[] ba,int str,int len) {
    try {
        for(int xa=0; xa<10; xa++) {
            try {
                textArea.append(new String(ba,str,len));
                break;
            } catch(Throwable thr) {
                if (xa==9) {
                    thr.printStackTrace();
                } else {
                    Thread.sleep(200);
                }
            }
        }
    } catch(Throwable thr) {
        CharArrayWriter caw=new CharArrayWriter();
        thr.printStackTrace(new PrintWriter(caw,true));
        textArea.append(System.getProperty("line.separator","n"));
        textArea.append(caw.toString());
    }
}
}

除了从事件处理程序调用"write"方法外,这种方法的工作效果非常好。

在事件处理程序中,在事件运行完成之前,不会将文本写入文本区域。我想要的是在命令运行时将文本写入控制台(这对于耗时的命令来说尤其需要)。换句话说,当用户按下回车键(例如)时,在将数据打印到JTextArea时会运行一个长进程,但直到整个进程运行后,文本才会显示。

有人知道我该怎么解决这个问题吗?

如果我理解正确,您正在某个事件处理程序中使用您的类,并在那里调用write方法。如果是这种情况,您可以使用SwingUtilities.invokeLater方法。例如:

http://www.javamex.com/tutorials/threads/invokelater.shtml

基本上,您可以沿着以下几行创建一个辅助方法:

private void writeOnEDT(final byte[] ba, final int str, final int len) {
  SwingUtilities.invokeLater(new Runnable() {
    public void run() {
      instance.write(ba, str, len); 
    }
  });
}

其中instancetextareaStream类的实例。如果您决定将其放在同一个类中,只需删除instance.并使用writeOnEDT而不是write,它应该可以正常工作。

请注意,无论您有什么长时间运行的作业,都必须不要在EDT上执行,否则,所有事件活动都将等待。您可以使用线程或执行器(另请参阅:http://www.baptiste-wicht.com/2010/09/java-concurrency-part-7-executors-and-thread-pools/)实现这一目标。这在很大程度上取决于你试图解决的问题。

Swing GUI类的方法应该始终在EDT线程上调用-例如,如果您感兴趣,请参阅以下内容以获得深入解释:

  • http://weblogs.java.net/blog/kgh/archive/2004/10/multithreaded_t.html
  • http://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html

风格上的一件事——你把你的课命名为textareaStream。Java类应该以大写字母开头,这是事实上的标准。

相关内容

  • 没有找到相关文章

最新更新