如何将 jProgress bar 用于 ProcessBuilder 进程? [英] How to use jProgress bar for ProcessBuilder process?

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

问题描述

我正在开发一个 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 的上下文之外创建或修改任何 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 支持的进度通知以及从后台线程和process<publish 数据的能力 在 EDT 的上下文中.它还有一个很好的 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 方法中重置其状态,但这确实稍等一下,不知道工作人员何时真正开始,当然,您应该在调用工作人员之前设置状态,但是,管理用户界面的状态仍然不是工作人员的责任

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

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

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