入门例子是从参考文献2与3中粘过来的内容。
在Swing中,若是须要重定向System.err和System.out到一个JTextPane或一个JTextArea,你仅须要覆写OutputStream类的write()方法,以追加文本到文本组件。下面给一个关于JTextArea的例子。html
private JTextArea textArea = new JTextArea(4, 25); // 本质上至关于多线程的更新JTextArea内容 private void updateTextArea(final String text) { SwingUtilities.invokeLater(new Runnable() { public void run() { textArea.append(text); } }); } private void redirectSystemStreams() { OutputStream out = new OutputStream() { @Override public void write(int b) throws IOException { updateTextArea(String.valueOf((char) b)); } @Override public void write(byte[] b, int off, int len) throws IOException { updateTextArea(new String(b, off, len)); } @Override public void write(byte[] b) throws IOException { write(b, 0, b.length); } }; System.setOut(new PrintStream(out, true)); System.setErr(new PrintStream(out, true)); } @Test public void run() { // 使用,调用redirectSystemStreams()便可。 redirectSystemStreams(); // 下面这句话会转向textArea中输出 System.out.println("hello, world"); }
redirectSystemStreams方法,本质上是多线程的更新JTextArea内容。在处理Swing上的点击事件时,事件处理返回以前,其余事件是不能触发的,界面相似于卡住的情况。
所以,在Swing点击事件结束后,更新JTextArea内容的线程才能运行,这样的效果是内容输出是非实时的。
怎样解决这个问题呢?在事件处理函数里面,重开一个线程,在这个新开的线程里面,执行比较耗时的计算与相应的打印内容。这样的话,事件处理函数所在的线程会快速的线束,其它更新Swing的JTextArea内容的线程才能被执行。
下面以伪代码的形式,给出一个例子,说明事件处理函数的写法。java
public class InstallBtnListener implements ActionListener { // 日志页面类,该类有一个JTextArea属性,是打印内容目标输出位置; private LogFrame logFrame = new LogFrame(); public InstallBtnListener() { super(); // 使输出转向JTextArea; // 这里我封闭了个类,重点是,将JTextArea传过去,且调用redirectSystemStreams方法 new RedirectingPrint(logFrame.getTextArea()).redirectSystemStreams(); } @Override public void actionPerformed(ActionEvent e) { // 在事件处理函数里面,重开一个线程,在这个新开的线程里面,执行比较耗时的计算与相应的打印内容 new Thread(new Runnable() { @Override public void run() { // 比较耗时的计算与相应的打印内容代码写在这里 } }).start(); } } // JButton点击事件 jbutton.addActionListener(new InstallBtnListener());
以上,就解决了输出实时性的问题。
下面有一段话,从参考文献1中粘过来的,用它来总结下这个问题。多线程
通常说来,耗时的操做不该该在事件处理方法中执行,由于事件处理返回以前,其余事件是不能触发的,界面相似于卡住的情况,因此在独立的线程上执行比较耗时的操做可能更好,这会当即更新用户界面和释放事件派发线程去派发其余的事件。
[1] https://blog.csdn.net/yiziwei... (java基础学习总结——java.awt.EventQueue.invokeLater干什么用的)
[2] https://billwaa.wordpress.com... ([Java] GUI Console Output)
[3] http://unserializableone.blog... (Redirecting System.out and System.err to JTextPane or JTextArea)
[4] https://stackoverrun.com/cn/q... (如何在eclipse中打印到textArea而不是控制台?)
[5] https://stackoverflow.com/que...app