我正在使用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());
}
}
}这是很好的工作,除非“写”方法是从事件处理程序调用的。
在事件处理程序中,在事件运行结束之前,文本不会写入文本区域。我想要的是在命令运行时将文本写入控制台(这对于耗时的命令尤其需要)。换句话说,当用户按下enter键(例如)时,一个长进程在将数据打印到JTextArea时运行,但是直到整个进程运行之后文本才会显示出来。
有没有人知道我该怎么处理这件事?
发布于 2012-02-14 03:47:33
如果我正确地理解了您的意思,那么您将在某个事件处理程序中使用您的类,并在其中调用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);
}
});
}其中instance是textareaStream类的一个实例。如果您决定将它放在同一个类中,只需删除instance.并使用writeOnEDT而不是write,它就会正常工作。
注意,无论您有什么长时间运行的作业,都必须在EDT上执行而不是,否则,所有的事件活动都会等待。您可以使用线程或遗嘱执行人 (也请参阅此:http://www.baptiste-wicht.com/2010/09/java-concurrency-part-7-executors-and-thread-pools/)来实现这一目标。这在很大程度上取决于你想要解决的问题。
Swing GUI类的方法应该始终在EDT螺纹上调用,例如,如果您感兴趣,请参阅这些方法以获得深入的解释:
一件文体上的事情--你把你的班级命名为textareaStream。Java类应该以大写字母开头,这是一个事实上的标准。
https://stackoverflow.com/questions/9267664
复制相似问题