在处理时更新JProgressBar [英] updating a JProgressBar while processing
问题描述
我知道这个主题已经在许多问题上被看到并且已经得到了回答,但是,我仍然无法理解它。
I know the subject has already been seen on many Questions and has been answered, but still, I can't get trough it.
我只想在提取大型xml文件的某些内容时更新progressBar。
我认为在不同的线程中使用耗时的循环已足够了但是?..
我设法获得的是progressBar要么根本没有显示,要么在最后更新,就在之前它关闭了。
I just want to update a progressBar while extracting some stuff of a large xml file. I thought it was enough to have the time-consuming loop in a different thread but ?.. All I managed to get is the progressBar either not showed at all, or updated at the end, just before it's closed.
在应用程序启动附近的某个地方,我有:
Instanced somewhere near the launch of the application, I have:
public class SomeClass {
private SomeClass () {
myXMLParser reader = new myXMLParser();
CoolStuff fromXml = reader.readTheXml();
}
}
在显示和更新带有JProgressBar的JDialog时:
while showing and updating a JDialog with a JProgressBar:
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
事件更新progressBar,但示例总是给出 all-in-one ,其中处理和同一类中的进度条,以及类中的类,并且从Java开始,我无法将其转换为我的情况。
I have seen many things with SwingWorker
and using PropertyChange
events update the progressBar, but examples are always given all-in-one, with the processing and the progressbar within the same class, and with classes within classes, and since I begin in Java, I wasn't able to translate that to my situation.
任何帮助?..任何(不太明显)的建议?
Any help ?.. Any (not too obvious) advices ?
编辑:所以感谢btantlinger它的工作原理如下:
So thanks to btantlinger it worked like that:
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 Event Dispatch Thread上的JProgress栏。你无法在任何其他线程上修改Swing组件。
You MUST update the JProgress bar on the Swing Event Dispatch Thread. You cannot modify Swing components on any other thread.
你唯一的另一种选择是在开始你的线程之前将JProgress栏设置为indeterminate,其中进度条将只是来回走动。
Your only other alternative would be to set the JProgress bar "indeterminate" before you start your thread where the progress bar will just go back and forth.
例如
progBar.setIndeterminate(true);
参见SwingWorker javadoc:
http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html
See the SwingWorker javadoc: http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html
如果您不想使用SwingWorker,另一个选项是 SwingUtilities.invokeLater
方法
If you don't want to use the SwingWorker, another option is the SwingUtilities.invokeLater
method
//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);
}
});
这篇关于在处理时更新JProgressBar的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!