Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:使用自己的终端启动子进程_Java_Java Threads - Fatal编程技术网

Java:使用自己的终端启动子进程

Java:使用自己的终端启动子进程,java,java-threads,Java,Java Threads,我有两个控制器和一个启动它们的程序。 一个是生成数据的仿真器,另一个分析数据。 这两个控制器相互依赖,并使用RMI进行通信。 因此,我在另一个线程中启动模拟器,在主线程中启动分析器。 效果非常好。 现在的问题是,它们都在控制台上产生了相当多的输出,我真的希望它们打印到两个不同的终端。 有办法吗 我尝试将emulator作为新命令行中的子进程启动(下一步将是平台独立性) 但是,classpath太长,cmd.exe的输出是命令行太长。 您知道如何使用自己的输出终端生成另一个线程或进程吗? 我很乐意

我有两个控制器和一个启动它们的程序。 一个是生成数据的仿真器,另一个分析数据。 这两个控制器相互依赖,并使用RMI进行通信。 因此,我在另一个线程中启动模拟器,在主线程中启动分析器。 效果非常好。

现在的问题是,它们都在控制台上产生了相当多的输出,我真的希望它们打印到两个不同的终端。 有办法吗

我尝试将emulator作为新命令行中的子进程启动(下一步将是平台独立性)

但是,
classpath
太长,
cmd.exe
的输出是
命令行太长。

您知道如何使用自己的输出终端生成另一个线程或进程吗? 我很乐意接受任何建议

干杯

更新

我将OlaviMustanoja的答案与这个解决方案结合起来

它现在使用标准的
System.out
System.err
和堆栈跟踪。而且,它会滚动

public class ConsoleWindow implements Runnable {

    private String title;
    private JFrame frame;
    private JTextArea outputArea;
    private JScrollPane scrollPane;

    public ConsoleWindow(String title, boolean redirectStreams) {
        this.title = title;
        this.outputArea = new JTextArea(30, 80);
        this.outputArea.setEditable(false);

        if (redirectStreams)
            redirectSystemStreams();
    }

    public ConsoleWindow(String title) {
        this(title, false);
    }

    @Override
    public void run() {
        frame = new JFrame(this.title);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        scrollPane = new JScrollPane(outputArea);
        JPanel outputPanel = new JPanel(new FlowLayout());
        outputPanel.add(scrollPane);

        frame.add(outputPanel);
        frame.pack();
        frame.setVisible(true);
    }

    private void updateTextArea(final String text) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                outputArea.append(text);
            }
        });
    }

    private void redirectSystemStreams() {
        OutputStream out = new OutputStream() {
            @Override
            public void write(int b) throws IOException {
                updateTextArea(String.valueOf((char) b));
            }

            @Override
            public void write(byte[] b, int off, int len) throws IOException {
                updateTextArea(new String(b, off, len));
            }

            @Override
            public void write(byte[] b) throws IOException {
                write(b, 0, b.length);
            }
        };

        System.setOut(new PrintStream(out, true));
        System.setErr(new PrintStream(out, true));
    }

    public void println(String msg) {
        updateTextArea(msg + "\n");
    }

    public void println(Throwable t) {
        println(t.toString());
    }

    public void print(String msg) {
        updateTextArea(msg);
    }

    public void printStackTrace(Throwable t) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        t.printStackTrace(pw);
        this.println(sw.toString());
    }
}
是否需要将消息输出到这些控制台?如果没有,您可以简单地实现一个类(比如OutputWindow),它以某种方式接收消息并在窗口中显示它们

<> >为了更好地说明我在评论中所提出的观点,请考虑下面的代码实现<代码> OutPutsWindows < /C> >:

class OutputWindow implements Runnable {

    private String title;
    private JFrame frame;
    private JTextArea outputArea;

    public OutputWindow(String title) {
        this.title = title;
        this.outputArea = new JTextArea(15, 50);
        this.outputArea.setEditable(false);
    }

    @Override
    public void run() {
        frame = new JFrame(this.title);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel outputPanel = new JPanel(new FlowLayout());
        outputPanel.add(outputArea);

        frame.add(outputPanel);
        frame.pack();
        frame.setVisible(true);
    }

    public void println(String msg) {
        outputArea.append(msg + "\n");
    }

    public void println(Throwable t) {
        this.println(t.toString());
    }

    public void print(String msg) {
        outputArea.append(msg);
    }

    public void printStackTrace(Throwable t) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        t.printStackTrace(pw);
        this.println(sw.toString());
    }

}
一段简单的、经过快速测试的代码。您可以打开一个新的“控制台”,如下所示:

OutputWindow console = new OutputWindow("Console");
SwingUtilities.invokeLater(console);
您可以尝试一下:

OutputWindow console = new OutputWindow("Console");
SwingUtilities.invokeLater(console);

try {
    System.out.println(2 / 0);     // just to throw an exception
} catch (ArithmeticException ex) {
    console.printStackTrace(ex);
}

这样做的好处是您可以自定义它的范围!无限的可能性。用超棒的颜色和任何您想要的功能创建您自己的最先进的控制台。

这里最简单的解决方案是将输出写入文件,手动打开您的终端并启动阻塞尾。

它们必须是终端(linux)/命令提示(windows)/其他内置控制台吗?我的意思是,你可以打开两个窗口并在其中添加文本。另一个进程将文本输出到windowA,另一个进程输出到windowB。这也是平台无关的。@olavimutanoja问得好!我不完全确定终端、命令提示和操作系统内置控制台之间的区别。你能用几句话详细说明一下吗?基本上我需要程序输出和(在出现异常的情况下)堆栈跟踪(
System.out
System.err
)。Windows命令提示符(cmd)的作用与linux中的终端相同。我的意思是,有必要将消息输出到这些控制台吗?如果没有,您可以简单地实现一个类(比如OutputWindow),它以某种方式接收消息并在窗口中显示它们。在我自己的机器上,我会这样做,但这是一个共享项目。那么文件放在哪里呢?那么,阻塞尾部的命令取决于平台。。。你明白了;)
OutputWindow console = new OutputWindow("Console");
SwingUtilities.invokeLater(console);

try {
    System.out.println(2 / 0);     // just to throw an exception
} catch (ArithmeticException ex) {
    console.printStackTrace(ex);
}