执行进程时 GUI 无法更新 (SwingUtilities.invokeLater)

发布于 2024-10-28 12:20:46 字数 2734 浏览 0 评论 0原文

参考我之前的问题 无法执行任何操作在 Process.Runtime.exec 语句行之前的操作,我已将代码更改为两部分,一个线程类 CmdExec ,它具有执行外部程序的所有代码,如下所示:

    public class CmdExec extends Thread
     {
     private String cmd;
     private File path;

      public CmdExec() {
      }

      public CmdExec(String cmd, File path) {
      this.cmd = cmd;
      this.path = path;
      }

      public void run(){

  try
    {
        Runtime rt = Runtime.getRuntime();
        Process proc = rt.exec(cmd , null, path);
        InputStream stderr = proc.getErrorStream();
        InputStreamReader isr = new InputStreamReader(stderr);
        BufferedReader br = new BufferedReader(isr);
        String line = null;
        System.out.println("<ERROR>");
        while ( (line = br.readLine()) != null)
            System.out.println(line);
        System.out.println("</ERROR>");
        int exitVal = proc.waitFor();
        System.out.println("Process exitValue: " + exitVal);
    } catch (Throwable t)
      {
        t.printStackTrace();
      }

并通过参考 jtahlborn 答案,我已经完成另一个用于 GUI 更新目的的 Runnable 类,如下所示:

       Runnable doWorkRunnable = new Runnable() {
        public void run() {
System.out.println("hello world");
btnTranscribe.setEnabled(false);
areaOutput.setEditable(false);
areaOutput.setEnabled(false);
areaOutput.setText("Performing segmentation, please wait till process is done\n"); }
        };

在实际运行 process.exec() 调用外部程序之前,我调用 SwingUtilities.invokeLater 来更改 GUI,如下所示:

    SwingUtilities.invokeLater(doWorkRunnable);
    Runtime rt = Runtime.getRuntime();
    Process proc = rt.exec(cmd , null, path);

但使用上面的所有代码,GUI 仍然失败更新,并且仅在该过程完成后更新。我在协调这两个可运行对象和线程的任何特定步骤上是否有错误?

预先感谢您的大力帮助和回答

P / S:我在 GUI 中按下按钮期间开始执行 CmdExec() ,如下所示:

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { 
     strSegment = "java -Xmx2024m -jar ./LIUM_SpkDiarization-4.2.jar / --fInputMask=" +               strAudioOut + "/%s.wav"
            + " --sOutputMask=" + strCtlOut + "/%s.ctl --sOutputFormat=ctl --            doCEClustering --cMinimumOfCluster=1 new3_20110331103858";

    CmdExec tryDemo = new CmdExec();
    tryDemo = new CmdExec(strSegment, fSegment);
    tryDemo.run();

    strExtract = "./sphinx_fe -i " + strAudioOut + "/new3_20110331103858.wav"
           + " -o " + strFeatureOut + "/new3_20110331103858.mfc";
    //System.out.println (strExtract);
    //executeCommand (strExtract, fExtract);

    tryDemo = new CmdExec(strExtract, fExtract);
    tryDemo.run();
      }

referring to my previous question at Unable to perform any action before Process.Runtime.exec statement line, I have changed my code into two part, a thread class CmdExec that has all code to execute an external program as below:

    public class CmdExec extends Thread
     {
     private String cmd;
     private File path;

      public CmdExec() {
      }

      public CmdExec(String cmd, File path) {
      this.cmd = cmd;
      this.path = path;
      }

      public void run(){

  try
    {
        Runtime rt = Runtime.getRuntime();
        Process proc = rt.exec(cmd , null, path);
        InputStream stderr = proc.getErrorStream();
        InputStreamReader isr = new InputStreamReader(stderr);
        BufferedReader br = new BufferedReader(isr);
        String line = null;
        System.out.println("<ERROR>");
        while ( (line = br.readLine()) != null)
            System.out.println(line);
        System.out.println("</ERROR>");
        int exitVal = proc.waitFor();
        System.out.println("Process exitValue: " + exitVal);
    } catch (Throwable t)
      {
        t.printStackTrace();
      }

and by referring to jtahlborn answer, I have done another Runnable class for GUI update purpose as well, as below:

       Runnable doWorkRunnable = new Runnable() {
        public void run() {
System.out.println("hello world");
btnTranscribe.setEnabled(false);
areaOutput.setEditable(false);
areaOutput.setEnabled(false);
areaOutput.setText("Performing segmentation, please wait till process is done\n"); }
        };

I call to SwingUtilities.invokeLater to change the GUI before actually running the process.exec() to call external program as showed below:

    SwingUtilities.invokeLater(doWorkRunnable);
    Runtime rt = Runtime.getRuntime();
    Process proc = rt.exec(cmd , null, path);

but with all codes above, the GUI still failed to update and it is only updated after the process is done. Am I wrong at any particular steps in coordinating these two runnable and threads?

Thank in advance for your great help and answer

P / S: I start execute CmdExec() during a button is pressed in the GUI as below:

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { 
     strSegment = "java -Xmx2024m -jar ./LIUM_SpkDiarization-4.2.jar / --fInputMask=" +               strAudioOut + "/%s.wav"
            + " --sOutputMask=" + strCtlOut + "/%s.ctl --sOutputFormat=ctl --            doCEClustering --cMinimumOfCluster=1 new3_20110331103858";

    CmdExec tryDemo = new CmdExec();
    tryDemo = new CmdExec(strSegment, fSegment);
    tryDemo.run();

    strExtract = "./sphinx_fe -i " + strAudioOut + "/new3_20110331103858.wav"
           + " -o " + strFeatureOut + "/new3_20110331103858.mfc";
    //System.out.println (strExtract);
    //executeCommand (strExtract, fExtract);

    tryDemo = new CmdExec(strExtract, fExtract);
    tryDemo.run();
      }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

过潦 2024-11-04 12:20:46

你需要调用tryDemo.start(),而不是tryDemo.run()。您直接运行线程,而不是生成单独的调用。

you need to call tryDemo.start(), not tryDemo.run(). you are running the thread directly, not spawning a separate invocation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文