2009-08-07 28 views
2

私は実際にスレッドの作業に慣れていないので、誰かがこれを行うための最善の方法を見つけ出すのを助けてくれることを願っていました。スレッドとProcessBuilderの使用

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

外部のpythonファイルを呼び出すコード内にp.waitFor()があります。ボタンをクリックすると、プロセスが終了するまでボタンがハングアップします(アプリケーション全体が実際にハングします)。終わらせる。明らかに、私はこのプロセスが進行している間、ユーザが残りのアプリケーションとやり取りできるようにしたいが、完了するとすぐに私のアプリケーションに知ってほしいので、ファイルをアプレットにロードできるようにする。

これを行うにはどのような方法が最適ですか?

ありがとうございました。

答えて

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(); 
} 
+0

本当にありがとうございました...私は1つの可能性のあるアプローチを説明すると思うのlog4jロガーの存在を前提とし、いくつかのサンプルコードです。私はSwingWorkerが存在することさえ知りませんでしたが、それは完全に機能しました。 – knt

0

本当に、新しいプロセスを監視するための新しいスレッドを作成する必要があります。あなたが発見したように、UIの両方に1つのスレッドを使用し、子プロセスを監視すると、子プロセスが実行されている間、UIがハングアップしているように見えます。

はここ

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 
+0

SWTを暗示するJButtonについてはあまり考えていませんでした。これはSWTやコンソールアプリケーションでも同じように動作する多少一般的なアプローチです... – jharlap

+0

新しいスレッドを作成する必要がありますが、この。 [ProcessBuilder](http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html)も使用する必要があります。 –

関連する問題