java gui console_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 参考文献

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值