System.setOut与PipedOutputStream

时间:2013-11-27 15:23:14

标签: java swing console swingworker

我使用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();
    }
}

这是我的输出..
Output

单击该按钮时,System.out.println无法使用textarea。我不知道我做错了什么。

2 个答案:

答案 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以了解其他方法。