我正在开发一个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组件的状态.
有关详细信息,请参见Concurrency in Swing.
您可以使用线程在其中运行该过程,但您将负责确保您要对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;
}
}
现在,您可能想要将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();
这使您可以决定如何响应工作人员,而无需将您与特定工作流程联系起来.
见Worker Threads and SwingWorker