java - 进度监视器(不确定)显示后端执行情况

标签 java multithreading process progress-bar processbuilder

我正在我的java程序中使用Processbuilder在后端执行外部进程。我正在使用process.waitFor来获取进程的退出状态。后端进程需要时间,这取决于提供的输入。所以我需要在进程完成之前制作一个不确定时间的进度条。这只是为了通知用户后端有一个进程正在进行。

    try {
        button.setEnabled(false);
        this.progressbar.setVisible(true);
        this.progressbar.setIndeterminate(true);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        perform(this);
    }
}                                    

public void perform(JFrame f)
{
            String cmd[]={"cmd", "/c","a.exe:};
            ProcessBuilder pb = new ProcessBuilder(cmd);
            pb.directory(new File(dir_path));
            pb.redirectErrorStream(true);
            try {
                    p = pb.start();
                } catch (IOException ex) {
                    Logger.getLogger(execution.class.getName()).log(Level.SEVERE, null, ex);
                       }
            try
            {
               int exitVal = p.waitFor();
               if(exitVal>0)
               {
                   this.progressbar.setVisible(false);
                   this.progressbar.setIndeterminate(false);
                   this.button.setEnabled(true);
               }
               if(p.waitFor()==0)
               {
                   this.progressbar.setVisible(false);
                   this.progressbar.setIndeterminate(false);

                   JOptionPane.showMessageDialog(f,"Scan completed successfully.");
               }
             } catch (InterruptedException ex) {
    Logger.getLogger(execution.class.getName()).log(Level.SEVERE, null, ex);
}
}

Button 是调用该调用的按钮的名称。但我面临的问题是函数调用执行是在不执行这些语句的情况下进行的。

    try {
        button.setEnabled(false);
        this.progressbar.setVisible(true);
        this.progressbar.setIndeterminate(true);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

执行该函数后按钮将被禁用。 1)我可以知道为什么会发生这种情况吗? 2)我可以知道让进度条指示后端进度直到完成的解决方案吗?

提前致谢。

最佳答案

我建议使用 SwingWorker。它就是为了解决诸如此类的问题而设计的。以下是我的代码库中一些代码的片段(vui 是 JFrame):

vui.clearOutput();
vui.setOutput("Waiting for items to copy...\n"
            + "This could take several minutes. Please standby...");
vui.disableExit();
vui.disableInput();
vui.disableNext();
vui.showProgressBar();

// make thread so you can disable all options when zipping and enable progress bar
SwingWorker transferWorker = new SwingWorker() {
    @Override
    protected Void doInBackground() throws Exception {
        try {
            Process p = Runtime.getRuntime().exec("resources/bin/transferCopier.bat");

            StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "ERROR");
            StreamGobbler outputGobbler = new StreamGobbler(p.getInputStream(), "OUTPUT");
            errorGobbler.start();
            outputGobbler.start();

            p.waitFor();
        } catch (IOException ex) {
            Logger.getLogger(VaderController.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InterruptedException ie) {
            Logger.getLogger(VaderController.class.getName()).log(Level.SEVERE, null, ie);
        }
        return null;
    }
    @Override
    public void done() {
        vui.hideProgressBar();
        vui.clearOutput();
        vui.setOutput("Transfer Complete!\n\n"
                    + "Push \"Exit\" to quit.\n\n");
        vui.enableExit();
        mode = VaderMode.END;
    }
};
transferWorker.execute();

当执行transferWorker.execute();时,doInBackground()被调用。一旦 doInBackground() 完成计算,就会调用 done()done() 是您对 GUI 进行任何最终更新的地方。

关于上面的代码,需要注意的关键事项是,我在执行 SwingWorker 之前启用进度条,然后当 SwingWorker 执行完成时,我禁用进度条.

资源:

http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

关于java - 进度监视器(不确定)显示后端执行情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15901648/

相关文章:

java - 为什么我的按钮不起作用?

java - 确保所有等待线程完成

java - Android - 在运行任务时更新 UI?

c# - 在Windows服务中使用计时器

node.js - 使用 edge.js .Net C# 模块是否可以调用流程的 node.js 部分,即进行反向调用?

java - 无法调用index.jsp

java - 持久化图形数据 (Java)

debugging - 能够从进程 ID 识别进程身份的最佳 erlang 方法是什么?

java - 如何选择 ArrayList 中元素的索引并更改其属性之一?

java - 使用 bufferreader 在 java 代码中读取 --traceroute 命令时搜索特定单词