Запуск скрипта Python из приложения javafx - PullRequest
0 голосов
/ 28 мая 2018

Я хочу запустить некоторые скрипты Python из приложения javafx.Для запуска скриптов я использую этот код:

private String executeCommand(String command) {
    StringBuffer output = new StringBuffer();
    Process p;
    try {
        System.out.println(command);
        p = Runtime.getRuntime().exec(command);
        p.waitFor();
        BufferedReader reader =
                new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line = "";
        while ((line = reader.readLine())!= null) {
            output.append(line + "\n");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return output.toString();
}

public void launchCommand(String inputDir, String outputDir) {
    String command = ".\\venv\\Scripts\\python.exe ./test.py -i " + inputDir + " -o " + outputDir;
    String output = this.executeCommand(command);
    System.out.println(output);
}

Проблема в том, что скрипт запускается графическим потоком javafx, поэтому строка

p.waitFor();

заблокирует поток javafx и поэтому мойGUI перестает отвечать ...

Я не знаю, как решить эту проблему ... Заранее спасибо за помощь!

1 Ответ

0 голосов
/ 28 мая 2018

Просто запустите сценарий в фоновом потоке и убедитесь, что вы обновили GUI обратно в потоке приложения FX, либо используя Platform.runLater(...), либо инкапсулировав команду как Task и используя обработчик setOnSucceeded.Лучшая практика здесь - использовать ExecutorService для управления потоками.

Например:

private final ExecutorService exec = Executors.newCachedThreadPool();

public void launchCommand(String inputDir, String outputDir) {
    String command = ".\\venv\\Scripts\\python.exe ./test.py -i " + inputDir + " -o " + outputDir;
    Task<String> commandTask = new Task<String>() {
        @Override
        protected String call() {
            return executeCommand(command);
        }
    };
    commandTask.setOnSucceeded(event -> {
        // this is executed on the FX Application Thread, 
        // so it is safe to update the UI here if you need
        System.out.println(commandTask.getValue());
    });
    commandTask.setOnFailed(event -> {
        commandTask.getException().printStackTrace();
    });
    exec.execute(commandTask);

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...