我使用JTextArea开发了一个小型控制台。我读了一些教程,知道一些事情。但我还是有问题。这是我的代码。
public class Console extends JFrame {
public Console() throws IOException {
setSize(492, 325);
setLayout(new BorderLayout());
setDefaultCloseOperation(3);
setVisible(true);
final JTextArea area = new JTextArea();
add(area, BorderLayout.CENTER);
JButton button = new JButton("test");
add(button, BorderLayout.EAST);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Test with Button Click.."); // this is not print in textarea.
}
});
final PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream(pis);
System.out.println("Test Before setOut.");
System.setOut(new PrintStream(pos, true));
System.out.println("Test After setOut."); // this is printed in my textarea.
new SwingWorker<Void, String>() {
@Override
protected Void doInBackground() throws Exception {
Scanner scan = new Scanner(pis);
while (scan.hasNextLine())
area.append(scan.nextLine());
return null;
}
}.execute();
}
public static void main(String[] args) throws Exception {
new Console();
}
}
这是我的输出..
单击该按钮时,System.out.println无法使用textarea。我不知道我做错了什么。
答案 0 :(得分:2)
当您致电SwingWorker.execute()
时,它只会运行一次。所以在这里,它会读取第一个println()
,到达文档的末尾,然后停止运行。
更好的解决方案是实现您自己的OutputStream
并将write()
方法附加到文本区域,使用SwingUtilities.invokeLater()
确保在AWT线程上完成此操作。< / p>
大致像这样:
class TextAreaOut extends OutputStream implements Runnable {
JTextArea text;
String buffer = "";
TextAreaOut(JTextArea text) {
this.text = text;
System.setOut(new PrintStream(this));
}
@Override
public synchronized void run() {
text.append(buffer);
buffer = "";
}
@Override
public synchronized void write(int b) throws IOException {
if(buffer.length() == 0) {
SwingUtilities.invokeLater(this);
}
buffer += (char)b;
}
}
答案 1 :(得分:2)
我发现使用管道流混乱。您可以查看Message Console以了解其他方法。