编辑:我已经编辑了帖子以澄清我的问题,现在我本人已经有了更多的了解。
正如标题所示,我实质上是在执行应用程序任务时尝试将控制台输出到GUI中的JTextArea
。
这是我目前正在做的事情:
public class TextAreaOutputStream extends OutputStream
{
private final JTextArea textArea;
private final StringBuilder sb = new StringBuilder();
public TextAreaOutputStream(final JTextArea textArea)
{
this.textArea = textArea;
}
@Override
public void flush()
{
}
@Override
public void close()
{
}
@Override
public void write(int b) throws IOException
{
if (b == '\r')
return;
if (b == '\n')
{
final String text = sb.toString() + "\n";
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
textArea.append(text);
}
});
sb.setLength(0);
}
sb.append((char) b);
}
}
上面的内容将成功地将
System.out
重定向到我的上面的输出流,因此将事件发送给EventQueue
以更新我的GUI(JTextArea
)。这是问题所在:
当前使用
invokeLater()
将按照文档上的说明进行操作:Causes runnable to have its run method called in the dispatch thread of the EventQueue. This will happen after all pending events are processed.
因此,我真正想做的是在处理EventQueue中的所有其他内容之前,先对GUI执行更新(称为
run()
)。是否可以将事件本质上注入(inject)到我的EventQueue中?还是有人可以指点我看这个领域的不错的教程?
谢谢,
最佳答案
下面的示例创建带有文本区域的框架,并将System.out重定向到它:
import java.awt.BorderLayout;
import java.awt.Container;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class JTextAreaOutputStream extends OutputStream
{
private final JTextArea destination;
public JTextAreaOutputStream (JTextArea destination)
{
if (destination == null)
throw new IllegalArgumentException ("Destination is null");
this.destination = destination;
}
@Override
public void write(byte[] buffer, int offset, int length) throws IOException
{
final String text = new String (buffer, offset, length);
SwingUtilities.invokeLater(new Runnable ()
{
@Override
public void run()
{
destination.append (text);
}
});
}
@Override
public void write(int b) throws IOException
{
write (new byte [] {(byte)b}, 0, 1);
}
public static void main (String[] args) throws Exception
{
JTextArea textArea = new JTextArea (25, 80);
textArea.setEditable (false);
JFrame frame = new JFrame ("stdout");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
Container contentPane = frame.getContentPane ();
contentPane.setLayout (new BorderLayout ());
contentPane.add (
new JScrollPane (
textArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED),
BorderLayout.CENTER);
frame.pack ();
frame.setVisible (true);
JTextAreaOutputStream out = new JTextAreaOutputStream (textArea);
System.setOut (new PrintStream (out));
while (true)
{
System.out.println ("Current time: " + System.currentTimeMillis ());
Thread.sleep (1000L);
}
}
}