1 簡單入門例子
在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 總結
以上,就解決了輸出實時性的問題。
下面有一段話,從第一個參考文獻中粘過來的,用它來總結下這個問題。
總結:一般說來耗時的操作不應該在事件處理方法中執行,因爲事件處理返回之前,其他事件是不能觸發的,界面類似於卡住的狀況,所以在獨立的線程上執行比較耗時的操作可能更好,這會立即更新用戶界面和釋放事件派發線程去派發其他的事件。
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...
標題
一級標題
二級標題
三級標題
四級標題
五級標題
六級標題
無序序列表
- 文本1
- 文本2
- 文本3
有序序列表
- 文本1
- 文本2
- 文本3
插入文本鏈接
插入圖片鏈接
引用
一盞燈, 一片昏黃; 一簡書, 一杯淡茶。 守着那一份淡定, 品讀屬於自己的寂寞。 保持淡定, 才能欣賞到最美麗的風景! 保持淡定, 人生從此不再寂寞。
粗體和斜體
一盞燈, 一片昏黃;一簡書, 一杯淡茶。 守着那一份淡定, 品讀屬於自己的寂寞。 保持淡定, 才能欣賞到最美麗的風景! 保持淡定, 人生從此不再寂寞。
代碼引用
引用的語句爲單行
hello world
引用的語句爲多行
//sdfsdfsdf
int a = 10;
int b = 10;
b = a + 10;
表格
Tables | Are | Cool |
---|---|---|
col 3 is | right-aligned | $1600 |
col 2 is | centered | $12 |
zebra stripes | are neat | $1 |
列名1 | 列名2 |
---|---|
首行(1,1) | 首行(2,1) |