1

我一直在尝试使用自定义输出流在 Jtext 区域上显示可执行文件的输出。

可执行文件是通过一个按钮调用的

        try {
            Process p = Runtime.getRuntime().exec("cgminer.exe" + " -o " + Infos.Address + ":" + Infos.Port + " -u " + Infos.User + " -p " + Infos.Password);
            p.waitFor();

            String line;

            BufferedReader error = new BufferedReader(new InputStreamReader(p.getErrorStream()));
            while((line = error.readLine()) != null){
                System.out.println(line);
            }
            error.close();

            BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
            while((line=input.readLine()) != null){
                System.out.println(line);
            }

            input.close();

            OutputStream outputStream = p.getOutputStream();
            PrintStream printStream = new PrintStream(outputStream);
            printStream.println();
            printStream.flush();
            printStream.close();
        }
            catch (Exception e) {
                // ...
              }
    }

}

然后将输出定向到jtext

public class CustomOutputStream extends OutputStream {
    private JTextArea textArea;

    public CustomOutputStream(JTextArea textArea) {
        this.textArea = textArea;
    }

    @Override
    public void write(int b) throws IOException {
        textArea.append(String.valueOf((char) b));
        textArea.setCaretPosition(textArea.getDocument().getLength());
    }
}

我的问题是当我调用第一个类时,按钮锁定并且没有输出到 jtext。只有当我强制关闭 cgminer 时才会出现输出。

任何帮助都非常感谢,因为这让我的大脑扭曲了。

4

1 回答 1

3

我的问题是当我调用第一个类时,按钮锁定并且没有输出到 jtext。只有当我强制关闭 cgminer 时才会出现输出。

这是捆绑 Swing 事件线程的典型症状。当您在 Swing 事件线程(也称为EDT或Event D ispatch T线程)上运行一段长时间运行的代码时,您可以有效地阻止线程执行包括绘制 GUI 和与用户交互在内的杂务”冻结”GUI。

解决方案不是waitFor()像另一个建议那样评论它,而是在后台线程(例如 SwingWorker)中运行它和任何其他阻塞代码。当您执行此操作时,请务必注意仅在事件线程上更新您的 Swing GUI。SwingWorker 有一种通过其发布和处理方法执行此操作的内置方法。

有关这方面的详细信息,请查看Swing 中的并发

您还需要做更多的线程,因为您的代码的某些行是阻塞的,并且会阻止下游的行运行,直到它们解除阻塞,但是到那时所有重要的操作都已完成。例如这些块:

// this blocks
p.waitFor();

// this blocks both times you use it
while((line = error.readLine()) != null){
  System.out.println(line);
}
于 2013-08-13T00:22:02.907 回答