Java 如何将jProgress栏用于ProcessBuilder进程?

Java 如何将jProgress栏用于ProcessBuilder进程?,java,swing,netbeans,process,jprogressbar,Java,Swing,Netbeans,Process,Jprogressbar,我正在开发一个java应用程序,通过ProcessBuilder执行CMD命令,使usb驱动器可引导。这需要几秒钟的时间,因为我想显示一个jprogressbar来增加GUI,我已经尝试了,我不明白,请帮助我 这是我的代码: private void btn_StartActionPerformed(java.awt.event.ActionEvent evt) { String[] command ={"CMD", "/C", "MyCmdCommand"};

我正在开发一个java应用程序,通过ProcessBuilder执行CMD命令,使usb驱动器可引导。这需要几秒钟的时间,因为我想显示一个jprogressbar来增加GUI,我已经尝试了,我不明白,请帮助我

这是我的代码:

private void btn_StartActionPerformed(java.awt.event.ActionEvent evt)    
{
      String[] command ={"CMD", "/C", "MyCmdCommand"};
      ProcessBuilder probuilder = new ProcessBuilder( command );
      probuilder.directory(new File(dri+":\\"));   

      try 
      {
            Process process = probuilder.start();
            process.waitFor();
      }

      catch(IOException e)
      {
            JOptionPane.showMessageDialog(this, e);
      }
}
如何在代码中使用JProgressbar,以及在何处使用?

谢谢

Swing是单线程环境,它也不是线程安全的

这意味着任何长时间运行或阻塞的进程都不应该在事件调度线程的上下文中运行,因为这将阻止它处理新事件,包括重新绘制请求,使程序看起来像挂起了一样

这也意味着您不应该从EDT上下文之外创建或修改任何UI组件的状态

有关更多详细信息,请参阅

您可以使用
线程
在中运行流程,但您将负责确保您要对UI所做的任何更改都是在EDT的上下文中手动执行的。这可能会变得很麻烦,尤其是当您希望将信息从线程传递到EDT时

另一个解决方案是使用
SwingWorker
,它提供的功能可以更轻松地在后台线程和EDT之间同步数据。它支持通过
setProgress
方法和
PropertyListener
支持进行进度通知,并支持
从后台线程发布数据和
在EDT上下文中处理数据。它还有一个很好的
done
方法,可以让您知道后台线程何时完成,但它是在EDT的上下文中执行的,例如

public static class FormatWorker extends SwingWorker<Integer, Integer> {

    private String drive;

    public FormatWorker(String drive) {
        this.drive = drive;
    }

    @Override
    protected Integer doInBackground() throws Exception {
    String[] command = {"CMD", "/C", "MyCmdCommand"};
    ProcessBuilder probuilder = new ProcessBuilder(command);
    probuilder.directory(new File(drive + ":\\"));

    Process process = probuilder.start();
    return process.waitFor();
        return 0;
    }

}
    PropertyChangeListener listener = new PropertyChangeListener() {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            System.out.println(evt.getPropertyName() + "; " + evt.getNewValue());
            if ("state".equals(evt.getPropertyName())) {

                SwingWorker.StateValue state = (SwingWorker.StateValue) evt.getNewValue();
                switch (state) {
                    case DONE:
                        try {
                            int exitLevel = ((SwingWorker<Integer, ?>)evt.getSource()).get();
                            JOptionPane.showMessageDialog(null, "Format command completed with exit level of " + exitLevel);
                        } catch (InterruptedException | ExecutionException ex) {
                            JOptionPane.showMessageDialog(progressBar, ex.getMessage());
                        } finally {
                            progressBar.setIndeterminate(true);
                        }
                        break;
                    case STARTED:
                        progressBar.setIndeterminate(true);
                        break;
                }

            }
        }
    };
    FormatWorker worker = new FormatWorker("G");
    worker.addPropertyChangeListener(listener);
    worker.execute();
这允许您决定如何响应工作人员,而无需将您耦合到特定的工作流程


请参见

您需要在线程内执行cmd命令,并使用中间progressbaread命令会给出什么输出?我很确定您不希望在试图格式化的设备的根目录中执行命令…-1以发布潜在的危险代码。版主已经被标记。这个答案非常好。只是问你是否错过了setUndeterminate(true)或者它不需要?因为进度条已经传递给了工作人员,所以我假设是来电者设置的。就我个人而言,我更喜欢在worker上使用属性更改侦听器来监视完成状态,并让调用方处理所有事务,从worker上完全消除任何UI责任,但我没有时间了