lahiruhashan
lahiruhashan

Reputation: 120

Nothing happens until the external python command finish running in java

I have a logText(String text) function which basically shows some text in a text area. I need some text to be shown before running the external python command. But the text is shown after the execution of external python command. Here is my code.

    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);
        }

My logText() function.

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

How can I show the text in the text area before execution of python command?

Upvotes: 0

Views: 57

Answers (1)

saeed foroughi
saeed foroughi

Reputation: 1710

what you are doing is a classic example of running long-running code on GUI thread and as a result, freezing the main thread. The solution is the same as always (no matter what language or framework): run the long-running work in a background thread such as a new Thread(...) or a SwingWorker.

for example:

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();

p.s. as you can see in the comments the last two commands in the new thread needed to be called with SwingUtilities.invokeLater(...).

Upvotes: 2

Related Questions