我有一個Swing程序,其中的工作是在非Swing線程中不斷完成的。它通常需要更新一個JTextPane - 通常每秒多次。我意識到setText()需要從事件派發線程內部調用,但我無法弄清楚如何使這種情況順利進行。在多線程Swing程序中頻繁調用setText()
以下最小的完整示例儘可能接近使用PipedInputStream/PipedOutputStream對,但似乎每隔一秒左右更新一次屏幕。我不確定需要這麼長時間。
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
public class TextTest extends JFrame {
private JTextPane out = new JTextPane();
private PipedInputStream pIn = new PipedInputStream();
private PrintWriter pOut;
public TextTest() {
try {
pOut = new PrintWriter(new PipedOutputStream(pIn));
}
catch (IOException e) {System.err.println("can't init stream");}
add(new JScrollPane(out));
setSize(500, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
// Start a loop to print to the stream continuously
new Thread() {
public void run() {
for (int i = 0; true; i++) {
pOut.println(i);
}
}
}.start();
// Start a timer to display the text in the stream every 10 ms
new Timer(10, new ActionListener() {
public void actionPerformed (ActionEvent evt) {
try {
if (pIn.available() > 0) {
byte[] buffer = new byte[pIn.available()];
pIn.read(buffer);
out.setText(out.getText() + new String(buffer));
}
}
catch (IOException e) {System.err.println("can't read stream");}
}
}).start();
}
public static void main(String[] args) {
new TextTest();
}
}
我在執行這個錯誤嗎?對於如何從EDT外部持續更新JTextPane,我有完全錯誤的想法嗎?
您的鏈接是404頁面。 – jjnguy 2010-11-09 21:53:39
@jjnguy:我不知道爲什麼API鏈接是404-oracled,但版本7已經放棄了線程安全附帶條件;請考慮恢復您的答案,因爲這可能是更好的選擇。 – trashgod 2010-11-09 21:56:20
我不知道!我也不確定它是否解決了這個問題 - 這兩個線程仍然以某種方式破壞對方。我嘗試切換到一個StringBuilder,並重復從工作線程調用setText(),但顯示器是閃爍的,並且JScrollPane從不滾動到底部。如果你願意,我可以發佈更新的代碼,但我認爲我仍然需要一個從EDT更新的解決方案。 – Etaoin 2010-11-09 22:15:04