[英]updating a JProgressBar while processing
我知道这个主题已经在许多问题上看到并得到了回答,但我仍然无法理解它。
我只想在提取大型 xml 文件的一些内容时更新进度条。 我认为在不同的线程中进行耗时的循环就足够了,但是?.. 我设法得到的只是progressBar 要么根本没有显示,要么在结束时更新,就在它关闭之前。
在应用程序启动附近的某个地方,我有:
public class SomeClass {
private SomeClass () {
myXMLParser reader = new myXMLParser();
CoolStuff fromXml = reader.readTheXml();
}
}
使用 JProgressBar 显示和更新 JDialog 时:
public class LoadingDialog extends JDialog {
private JProgressBar progressBar;
/* ... */
public void progress() {
progressBar.setValue(progressBar.getValue() + 1);
}
}
所以我有这个myXMLParser :
public class myXMLParser {
private LoadingDialog loadingDialog = new LoadingDialog();
public CoolStuff readTheXml() {
CoolStuff fromXml = new CoolStuff();
while(manyIterations) {
loadingDialog.progress();
fromXml.add(some() + xml() + reading());
}
return fromXml;
}
}
我在SwingWorker
看到了很多事情,并且使用PropertyChange
事件更新了进度条,但是示例总是一体式给出,处理和进度条在同一个类中,以及类中的类,自从我开始使用 Java,我无法将其转化为我的情况。
有什么帮助吗?.. 有什么(不太明显的)建议吗?
编辑:所以多亏了 btantlinger,它的工作方式是这样的:
public class SomeClass {
private SomeClass () {
myXMLParser reader = new myXMLParser();
new Thread(new Runnable() {
@Override
public void run() {
CoolStuff fromXml = reader.readTheXml();
}
}).start();
}
}
public class LoadingDialog extends JDialog {
private JProgressBar progressBar;
/* ... */
public void progress() {
progressBar.setValue(progressBar.getValue() + 1);
}
}
public class myXMLParser {
private LoadingDialog loadingDialog = new LoadingDialog();
public CoolStuff readTheXml() {
CoolStuff fromXml = new CoolStuff();
while(manyIterations) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
loadingDialog.progress();
}
});
fromXml.add(some() + xml() + reading());
}
return fromXml;
}
}
您必须更新 Swing 事件调度线程上的 JProgress 栏。 您不能在任何其他线程上修改 Swing 组件。
您唯一的其他选择是在开始您的线程之前将 JProgress 栏设置为“不确定”,其中进度栏只会来回移动。
例如
progBar.setIndeterminate(true);
请参阅 SwingWorker javadoc: http : //docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html
如果您不想使用 SwingWorker,另一种选择是SwingUtilities.invokeLater
方法
//inside your long running thread when you want to update a Swing component
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//This will be called on the EDT
progressBar.setValue(progressBar.getValue() + 1);
}
});
除了@btanlinger 提供的代码,我经过测试发现还需要额外的一行代码,以便在处理时更新UI线程上的进度条。 见下文。
SwingUtilities.invokeLater(new Runnable() {
public void run() {
progressBar.setValue((int)percentage);
//below code to update progress bar while running on thread
progressBar.update(progressBar.getGraphics());
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.