2

私はスレッドの操作に本当に慣れていないので、誰かがこれを行うための最良の方法を見つけるのを手伝ってくれることを望んでいました.

Java アプリケーションに JButton があります...ボタンをクリックすると、外部の Python コードを実行するプロセスを作成する Process Builder があります。Python コードはいくつかのファイルを生成しますが、これには時間がかかる場合があります。Python コードの実行が完了したら、それらのファイルを Java アプリケーション内のアプレットにロードする必要があります。

現在の形式では、外部の python ファイルを呼び出すコード内に p.waitFor() があります...そのため、ボタンをクリックすると、プロセスが完了するまでボタンがハングします (アプリケーション全体が実際にハングします)。明らかに、このプロセスの実行中にユーザーがアプリケーションの残りの部分と対話できるようにしたいのですが、プロセスが完了したらすぐにアプリケーションにそれを知らせて、ファイルをアプレットにロードできるようにしたいと考えています。 .

これを行う最善の方法は何ですか?

ご協力いただきありがとうございます。

4

2 に答える 2

9

バックグラウンド スレッドで Python プロセスを呼び出すには、SwingWorkerを使用する必要があります。このようにして、実行時間の長いタスクが実行されている間、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 と子プロセスの監視の両方に 1 つのスレッドのみを使用すると、子プロセスの実行中に UI がハングしたように見えます。

これは、可能なアプローチの1つを説明すると思われる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 に答える