如何在ProcessBuilder流程中使用jProgress栏? [英] How to use jProgress bar for ProcessBuilder process?

查看:141
本文介绍了如何在ProcessBuilder流程中使用jProgress栏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发Java应用程序,以通过通过ProcessBuilder执行CMD命令使USB驱动器可启动.这需要几秒钟,因为我想显示一个jprogressbar以增加GUI,我已经尝试过这样做,但我没有得到,请帮助我.

I am developing an java application to make a usb drives bootable,by executing CMD command through ProcessBuilder. 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.

这是我的代码:

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以及必须在哪里使用?
谢谢

How i can use JProgressbar in my code and where i have to use?
thank you

推荐答案

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

Swing is a single threaded environment, it is also not thread safe.

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

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.

这还意味着您永远不要在EDT上下文之外创建或修改ANY UI组件的状态.

It also means that you should NEVER create or modify the state of ANY UI component from outside the context of the EDT.

有关更多详细信息,请参见 Swing中的并发.

See Concurrency in Swing for more details.

您可以使用Thread在其中运行该过程,但是您将负责确保要对UI进行的任何更改都在EDT上下文中手动进行.这可能会带来麻烦,尤其是当您要将信息从线程传递到EDT时.

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. This can become troublesome especially when you want to pass information from the thread to the EDT.

另一种解决方案是使用SwingWorker,该功能提供的功能可以更轻松地在其后台线程和EDT之间同步数据.它通过setProgress方法和PropertyListener支持来支持进度通知,并且能够在EDT上下文中从后台线程和process中获取publish数据.它还具有一个不错的done方法,该方法可以让您知道后台线程何时完成,但是在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. 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. 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...

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

}

现在,您可能会很想将JProgressBar传递给SwingWorker并在done方法中重置其状态,但这确实使它挂了一点点,不知道工作人员实际上是什么时候开始的,当然,您应该在致电工作人员之前设置状态,但是,管理UI状态不是工作人员的责任

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

例如,您可以利用工作人员PropertyChangeListener的支持...

Instead, you could take advantage of the workers PropertyChangeListener support, for example...

    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.

请参见工作线程和SwingWorker

这篇关于如何在ProcessBuilder流程中使用jProgress栏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆