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 に答える