Java,console输出实时的转向GUI textbox

1 简单入门例子

入门例子是从参考文献2与3中粘过来的内容。
  在Swing中,如果需要重定向System.err和System.out到一个JTextPane或一个JTextArea,你仅需要覆写OutputStream类的write()方法,以追加文本到文本组件。下面给一个关于JTextArea的例子。

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");
}

2 实时输出问题

redirectSystemStreams方法,本质上是多线程的更新JTextArea内容。在处理Swing上的点击事件时,事件处理返回之前,其他事件是不能触发的,界面类似于卡住的状况。
  因此,在Swing点击事件结束后,更新JTextArea内容的线程才能运行,这样的效果是内容输出是非实时的。
  怎样解决这个问题呢?在事件处理函数里面,重开一个线程,在这个新开的线程里面,执行比较耗时的计算与相应的打印内容。这样的话,事件处理函数所在的线程会快速的线束,其它更新Swing的JTextArea内容的线程才能被执行。
  下面以伪代码的形式,给出一个例子,说明事件处理函数的写法。

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());

3 总结

以上,就解决了输出实时性的问题。
  下面有一段话,从参考文献1中粘过来的,用它来总结下这个问题。

一般说来,耗时的操作不应该在事件处理方法中执行,因为事件处理返回之前,其他事件是不能触发的,界面类似于卡住的状况,所以在独立的线程上执行比较耗时的操作可能更好,这会立即更新用户界面和释放事件派发线程去派发其他的事件。

4 参考文献

[1] https://blog.csdn.net/yiziweiyang/article/details/52325308 (java基础学习总结——java.awt.EventQueue.invokeLater干什么用的)
[2] https://billwaa.wordpress.com/2011/11/14/java-gui-console-output/#comment-100 ([Java] GUI Console Output)
[3] http://unserializableone.blogspot.com/2009/01/redirecting-systemout-and-systemerr-to.html (Redirecting System.out and System.err to JTextPane or JTextArea)
[4] https://stackoverrun.com/cn/q/86020 (如何在eclipse中打印到textArea而不是控制台?)
[5] https://stackoverflow.com/questions/564759/how-to-redirect-all-console-output-to-a-gui-textbox

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容

  • //Clojure入门教程: Clojure – Functional Programming for the J...
    葡萄喃喃呓语阅读 3,650评论 0 7
  • 面向对象主要针对面向过程。 面向过程的基本单元是函数。 什么是对象:EVERYTHING IS OBJECT(万物...
    sinpi阅读 1,051评论 0 4
  • 下面是Java线程相关的热门面试题,你可以用它来好好准备面试。 1) 什么是线程? 线程是操作系统能够进行运算调度...
    冰箱哥哥阅读 519评论 0 2
  • 个人笔记,方便自己查阅使用 Contents Java LangAssignment, ReferenceData...
    freenik阅读 1,376评论 0 6
  • 1.import static是Java 5增加的功能,就是将Import类中的静态方法,可以作为本类的静态方法来...
    XLsn0w阅读 1,220评论 0 2