0

我有一个程序,我在其中调用另一个单独的程序来做一些工作(让我们称之为子流程),子流程需要一些时间来完成每个任务并在一个简单的控制台中显示进度。

问题是,当我尝试使用 BufferedReader 读取该控制台时,我自己的程序会等待子进程完成,然后再将每一行写入 TextArea。

这是我用来读取每一行的代码:

    JTextArea report = new JTextArea(20,40);
    report.setText("");
    try
            {
                Process p = new ProcessBuilder(command).start();
                p.waitFor();
                BufferedReader reader=new BufferedReader(new  InputStreamReader(p.getInputStream()));
                String line = reader.readLine();
                while(line!=null) 
                { 
                report.append(line+"\n");
                line=reader.readLine(); 
                }
            }
            catch(IOException e1){ error.setText("Failed to run toxpack");}
            catch(InterruptedException e2) {error.setText("Failed to run command");}

我试图研究线程,但它仍然不起作用。

如何在不等待整个子流程完成的情况下阅读每一行并将它们添加到我的 textArea 中。

编辑:添加了其余的代码,但我不确定它是否有很大帮助。我想说的是,我希望子流程输出的每一行都出现在我的 textArea 中。无需等待它完成。

4

1 回答 1

0

您应该创建另一个从进程中读取的线程,并更新 Swing 组件:

    final Process p = new ProcessBuilder("cat", "/etc/hosts").start();
    final BufferedReader br = new BufferedReader(new InputStreamReader(
            p.getInputStream()));

    final Runnable r = new Runnable() {
        @Override
        public void run() {
            try {
                try {
                    for (String line = br.readLine(); line != null; line = br
                            .readLine()) {
                        final String l = line;
                        System.out.println(l);
                        EventQueue.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                textArea.setText(textArea.getText() + "\n" + l);
                            }
                        });

                        Thread.sleep(50);
                    }
                } finally {
                    br.close();
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    };

    final Thread t = new Thread(r);
    t.start();

现在这些行在读取器线程中连续读取,并且 Swing 的更新使用 发布到 Swing 的事件队列中EventQueue.invokeLater,因为读取不是在 Swing 的事件调度线程中完成的(详细信息:何时使用 invokeLater)。

sleep只是让它慢一点(模拟数据缓慢流入)。

和...一起

public class TextAreaDemo {

public static void main(String[] args) {
    final JTextArea textArea = new JTextArea(60, 5);

    final JScrollPane sp = new JScrollPane(textArea,
            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS) {
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(600, 300);
        }

    };

    final JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(sp);
    frame.pack();
    frame.setVisible(true);

    // Add the reader snippet here
}

}

它将更新文本区域中的值。

于 2013-08-06T12:17:29.230 回答