资讯专栏INFORMATION COLUMN

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

ivydom / 1724人阅读

摘要:下面这句话会转向中输出实时输出问题方法,本质上是多线程的更新内容。在处理上的点击事件时,事件处理返回之前,其他事件是不能触发的,界面类似于卡住的状况。因此,在点击事件结束后,更新内容的线程才能运行,这样的效果是内容输出是非实时的。

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/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...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/72510.html

相关文章

  • python 使用PyQt5

    摘要:一安装二简单使用使用创建一个简单窗口创建一个应用对象参数是一个来自命令行的参数列表脚本可以在中运行。这是我们用来控制我们应用启动的一种方法。 一:安装PyQt5 pip install pyqt5 二:PyQt5简单使用1:使用PyQt5创建一个简单窗口 import sys from PyQt5 import QtWidgets #创建一个应用(Application)对象,sys...

    CoreDump 评论0 收藏0
  • JavaScript 表单脚本——“文本框脚本”注意要点

    摘要:属性可以设置文本框的初始值。特性则是用于指定文本框内可以接受的最大字符数。与这个方法对应的事件,在选择了文本框中的文本时事件触发。如阻止用户选择要调用之前或之后立即将焦点设置到文本框。 在HTML中,有两种方式来表现文本框: 一种是使用input元素的单行文本,另一种是使用textarea的多行文本框。 使用input方式,必须添加type,设置为text。 size特性,可以指定文...

    kk_miles 评论0 收藏0
  • h5实现一键复制到粘贴板 兼容ios

    摘要:是方法起始光标结束光标不兼容苹果复制文字必须手动触发点击事件或者其他事件,不能直接使用调用实现一键复制到粘贴板兼容兼容性补充移动端安卓手机微信和几个手机浏览器都可以用。 实现原理 采用document.execCommand(copy)来实现复制到粘贴板功能 复制必须是选中input框的文字内容,然后执行document.execCommand(copy)命令实现复制功能。初步实现方案...

    miracledan 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<