当前位置: 首页 > 面试题库 >

如何将jProgress栏用于ProcessBuilder进程?

龙晟睿
2023-03-14
问题内容

我正在开发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上下文之外创建或修改ANY UI组件的状态。

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

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

另一个解决方案是使用,SwingWorker它提供的功能可以更轻松地在其后台线程和EDT之间同步数据。它支持通过setProgress方法和支持进行进度通知PropertyListener,以及publish从后台线程和processEDT上下文中获取数据的功能。它还有一个很好的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;
    }

}

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

相反,您可以利用工人的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();

这使您可以决定如何响应工作人员,而无需将您与特定的工作流程联系在一起。

请参阅工作线程和SwingWorker



 类似资料:
  • 本文向大家介绍Java如何基于ProcessBuilder类调用外部程序,包括了Java如何基于ProcessBuilder类调用外部程序的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了Java如何基于ProcessBuilder类调用外部程序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1. demo1 2. demo02 以上就

  • 问题内容: 我正在尝试线程wx.ProgressDialog。我有一个进度线程课程 当我按下一个按钮时会被调用 当我运行thread1.start()时,我收到100此类警告,并且进度条不显示。 如何在wxPython中使用线程制作进度条? 问题答案: 所有wxPython小部件和操作都应在单个线程中。如果要让对话框由另一个线程控制,则必须使用计时器和队列从另一个线程向对话框发送消息。 我了解的另

  • 在下面的图片中,我试图将ImageView置于状态栏下。但这并没有发生。 图片截图在Android API 19 AndroidAPI 22上的图像截图 我在Android透明状态栏和actionbar(这个问题)上尝试实现同样的功能,但它不起作用。 活动的xml布局是 我还在onCreate()方法中尝试了以下代码 风格xml style-v21.xml AppTheme是活动中使用的样式。 编

  • 问题内容: 请移至第二次更新。 我不想更改此问题的先前上下文。 我正在使用Java应用程序中的wkhtmltoimage。 使用它的标准方法是- 。 根据他们的文档,如果我们编写一个URL而不是输入URL,则输入将转换为STDIN。 我正在使用- 现在,我无法弄清楚如何将输入流传输到此过程。 我有一个读入的模板文件,并在末尾附加了一个字符串: 如何通过管道传递到流程的? 更新- 遵循Andrzej

  • 问题内容: 我一直在尝试使用Java的ProcessBuilder在Linux中启动应“长期”运行的应用程序。该程序的运行方式是启动命令(在本例中,我正在启动媒体播放应用程序),允许其运行并检查以确保它没有崩溃。例如,检查PID是否仍处于活动状态,然后重新启动该进程(如果已终止)。 我现在遇到的问题是PID在系统中仍然有效,但是应用程序的GUI挂起了。我尝试将ProcessBuilder(cmd)

  • 问题内容: 我的数据库中有一列,该列具有各种字符数组,例如。 我有一个查询,我试图获得这些数组的聚合而没有成功: 623和625具有相同的值,因此结果应该是seids和的分组,但我一直不断遇到此错误: 如果删除部分代码,则确实会获得带有和返回的表。 问题答案: 标准聚合函数仅适用于基本类型,不适用于输入的数组类型。(但是 Postgres 9.5+ 具有该功能的新变体!) 您可以使用 此相关答案中