简体   繁体   English

如何在ProcessBuilder流程中使用jProgress栏?

[英]How to use jProgress bar for ProcessBuilder process?

I am developing an java application to make a usb drives bootable,by executing CMD command through ProcessBuilder. 我正在开发Java应用程序,以通过ProcessBuilder执行CMD命令使USB驱动器可启动。 This takes few seconds, in that i want to show an jprogressbar to increase GUI, i have tried so for, i dont get, Please help me. 这需要几秒钟,因为我想显示一个jprogressbar以增加GUI,我已经尝试过这样做,但我没有得到,请帮助我。

This is My Code : 这是我的代码:

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);
      }
}

How i can use JProgressbar in my code and where i have to use? 我如何在代码中使用JProgressbar以及必须在哪里使用?
thank you 谢谢

Swing is a single threaded environment, it is also not thread safe. Swing是单线程环境,它也不是线程安全的。

This means that any long running or blocking process should never be run within the context of the Event Dispatching Thread, as it will prevent it from processing new events, including repaint requests, making the program look like it's hung. 这意味着任何长时间运行或阻塞的进程都不应在“事件调度线程”的上下文中运行,因为它将阻止它处理新事件,包括重画请求,使程序看起来像已挂起。

It also means that you should NEVER create or modify the state of ANY UI component from outside the context of the EDT. 这也意味着您永远不要在EDT上下文之外创建或修改ANY UI组件的状态。

See Concurrency in Swing for more details. 有关更多详细信息,请参见Swing中的并发

You can use a Thread to run the process within, but you will become responsible for ensure that any changes you want to make to the UI are carried out within the context of the EDT manually. 您可以使用Thread在其中运行该进程,但是您将负责确保要对UI进行的任何更改都在EDT上下文中手动进行。 This can become troublesome especially when you want to pass information from the thread to the EDT. 特别是当您要将信息从线程传递到EDT时,这可能会变得很麻烦。

Another solution is to use a SwingWorker which provides functionality that can synchronise data between it's background thread and the EDT more easily. 另一个解决方案是使用SwingWorker ,它提供的功能可以更轻松地在其后台线程和EDT之间同步数据。 It supports progress notification via the setProgress method and PropertyListener support as well as the ability to publish data from the background thread and process within the context of the EDT. 它通过setProgress方法和PropertyListener支持来支持进度通知,并且能够从EDT上下文中的后台线程和process publish数据。 It also has a nice done method which lets you know when the background thread has completed, but which is executed within the context of the EDT, for example... 它还有一个很好的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;
    }

}

Now, you might be tempted to pass in the JProgressBar to the SwingWorker and reset its state within the done method, but this does leave it a hanging a little, not knowing when the worker has actually started, sure, you should set the state before you call the worker, but still, it's not the responsibility of the worker to manage the state of the UI 现在,您可能会想将JProgressBar传递给SwingWorker并在done方法中重置其状态,但这确实使它挂了一点点,不知道工作程序实际上是什么时候开始的,当然,您应该在设置状态之前您打电话给工作人员,但管理UI状态不是工作人员的责任

Instead, you could take advantage of the workers PropertyChangeListener support, for example... 相反,您可以利用工作人员的PropertyChangeListener支持,例如...

    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();

This allows you to decide how you want to respond to the worker, without coupling you to a particular work flow. 这使您可以决定如何响应工作人员,而无需将您与特定的工作流程联系在一起。

See Worker Threads and SwingWorker 请参阅工作线程和SwingWorker

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM