首页 > 解决方案 > 在外部 python 命令完成在 java 中运行之前什么都不会发生

问题描述

我有一个logText(String text)功能,它基本上在文本区域中显示一些文本。在运行外部 python 命令之前,我需要显示一些文本。但是文本是在执行外部 python 命令后显示的。这是我的代码。

    logText("Please Wait Until The Testing Is Finished");
    logText("Starting Testing...");

        String command = "python3 python/Predict.py";

        try {
            String line;
            Process process = Runtime.getRuntime().exec(command);

            process.waitFor();
            BufferedReader error = new BufferedReader(new InputStreamReader(process.getErrorStream()));

            error.close();

            BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));

            input.close();

            OutputStream outputStream = process.getOutputStream();
            PrintStream printStream = new PrintStream(outputStream);
            printStream.println();
            printStream.flush();
            printStream.close();
            logText("Images Created At Output Directory");
            logText("Testing Completed");
        } catch (IOException ex) {
            Logger.getLogger(MasterFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InterruptedException ex) {
            Logger.getLogger(MasterFrame.class.getName()).log(Level.SEVERE, null, ex);
        }

我的logText()职能。

private void logText(String logText) {
    if (logArea.getText().equals("")) {
        logArea.setText(">>> " + logText);
    } else {
        logArea.append(System.lineSeparator() + ">>> " + logText);
    }
}

如何在执行 python 命令之前在文本区域中显示文本?

标签: javapython

解决方案


您正在做的是在 GUI 线程上运行长时间运行的代码并因此冻结主线程的经典示例。解决方案与往常一样(无论是哪种语言或框架):在后台线程中运行长时间运行的工作,例如 new Thread(...) 或 SwingWorker。

例如:

logText("Please Wait Until The Testing Is Finished");
logText("Starting Testing...");
String command = "python3 python/Predict.py";

new Thread(new Runnable() {
    public void run() {
        try {
            String line;
            Process process = Runtime.getRuntime().exec(command);

            process.waitFor();
            BufferedReader error = new BufferedReader(new InputStreamReader(process.getErrorStream()));

            error.close();

            BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));

            input.close();

            OutputStream outputStream = process.getOutputStream();
            PrintStream printStream = new PrintStream(outputStream);
            printStream.println();
            printStream.flush();
            printStream.close();
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    // Here, we can safely update the GUI
                    // because we'll be called from the
                    // event dispatch thread
                    logText("Images Created At Output Directory");
                    logText("Testing Completed");
                }
            });
        } catch (IOException ex) {
           Logger.getLogger(MasterFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InterruptedException ex) {
        Logger.getLogger(MasterFrame.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}).start();

ps 正如您在评论中看到的那样,新线程中的最后两个命令需要使用SwingUtilities.invokeLater(...).


推荐阅读