我有一个 Swing 程序,其中的工作在非 Swing 线程中持续进行。它经常需要更新 JTextPane —— 每秒更新很多次。我意识到 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,我的想法是否完全错误?
最佳答案
setText()
“方法是线程安全的,尽管大多数 Swing 方法不是。有关更多信息,请参阅 How to Use Threads。”
附录:供引用,这里有一些 other approaches更新 EDT。另一件需要注意的事情是 javax.swing.Timer
的 Action 事件处理程序。在 EDT 上执行。这是我的变体:
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import javax.swing.text.DefaultCaret;
public class TextTest extends JFrame {
private JTextArea out = new JTextArea();
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");
}
DefaultCaret caret = (DefaultCaret) out.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
add(new JScrollPane(out));
setSize(300, 500);
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 {
out.append(String.valueOf((char) pIn.read()));
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
public static void main(String[] args) {
new TextTest();
}
}
关于java - 多线程Swing程序中频繁调用setText(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4138996/