2

我真的不熟悉使用线程,所以我希望有人能帮助我找出最好的方法来做到这一点。

我的 java 应用程序中有一个 JButton...当您单击该按钮时,我有一个 Process Builder,它创建一个执行一些外部 python 代码的进程。python 代码会生成一些文件,这可能需要一些时间。当 python 代码执行完毕后,我需要将这些文件加载​​到我的 Java 应用程序中的一个小程序中。

在当前的形式中,我在调用外部 python 文件的代码中有一个 p.waitFor() ......所以当你点击按钮时,按钮会挂起(整个应用程序实际上挂起),直到进程完成。显然,我希望用户能够在此过程进行时与应用程序的其余部分进行交互,但是一旦完成,我希望我的应用程序知道它,以便它可以将文件加载到小程序中.

做这个的最好方式是什么?

谢谢你的帮助。

4

2 回答 2

9

您应该使用SwingWorker在后台线程上调用 Python 进程。这样,您的 UI 将在长时间运行的任务运行时保持响应。

// Define Action.
Action action = new AbstractAction("Do It") {
  public void actionPerformed(ActionEvent e) {
    runBackgroundTask();
  }
}

// Install Action into JButton.
JButton btn = new JButton(action);

private void runBackgroundTask() {
  new SwingWorker<Void, Void>() {
    {
      // Disable action until task is complete to prevent concurrent tasks.
      action.setEnabled(false);
    }

    // Called on the Swing thread when background task completes.
    protected void done() {
      action.setEnabled(true);

      try {
        // No result but calling get() will propagate any exceptions onto Swing thread.
        get();
      } catch(Exception ex) {
        // Handle exception
      }
    }

    // Called on background thread
    protected Void doInBackground() throws Exception {
      // Add ProcessBuilder code here!
      return null; // No result so simply return null.
    }
  }.execute();
}
于 2009-08-07T16:52:10.167 回答
0

你真的想创建一个新线程来监控你的新进程。正如您所发现的,仅对 UI 和监视子进程使用一个线程会使 UI 在子进程运行时似乎挂起。

这是一些假设存在 log4j 记录器的示例代码,我认为这将说明一种可能的方法......

Runtime runtime = Runtime.getRuntime();
String[] command = { "myShellCommand", "firstArgument" };

try {

    boolean done = false;
    int exitValue = 0;
    Process proc = runtime.exec(command);

    while (!done) {
        try {
            exitValue = proc.exitValue();
            done = true;
        } catch (IllegalThreadStateException e) {
            // This exception will be thrown only if the process is still running 
            // because exitValue() will not be a valid method call yet...
            logger.info("Process is still running...")
        }
    }

    if (exitValue != 0) {
        // Child process exited with non-zero exit code - do something about failure.
        logger.info("Deletion failure - exit code " + exitValue);
    }

} catch (IOException e) {
    // An exception thrown by runtime.exec() which would mean myShellCommand was not 
    // found in the path or something like that...
    logger.info("Deletion failure - error: " + e.getMessage());
}

// If no errors were caught above, the child is now finished with a zero exit code
// Move on happily
于 2009-08-07T17:06:20.497 回答