2012-03-06 81 views
4

我知道这个问题已经在许多问题上看到,并已得到回答,但仍然无法通过它。更新JProgressBar,同时处理

我只想更新一个progressBar,同时提取一些大的xml文件的东西。 我认为这足以在不同的线程中耗费时间循环,但是...... 我设法获得的所有progressBar或者根本没有显示,或者在最后关闭之前更新。

实例化附近的某处启动该应用程序,我有:

public class SomeClass { 
    private SomeClass() { 
     myXMLParser reader = new myXMLParser(); 
     CoolStuff fromXml = reader.readTheXml(); 
    } 
} 

同时显示和更新一个JDialog用的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; 
    } 
} 

我见过很多东西w ith SwingWorker和使用PropertyChange事件更新progressBar,但总是给出示例all-in-one,处理和进度条在同一个类中,并且类中有类,并且自从我开始使用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; 
    } 
} 

回答

10

您必须更新在Swing事件分派线程的JProgress吧。您无法修改任何其他线程上的Swing组件。

你唯一的另一种选择是在开始你的线程之前设置JProgress栏“indeterminate”,在这里进度条会来回移动。

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); 


    } 
}); 
0

除由@btantlinger提供的代码,我在测试后发现它需要额外的一行代码才能更新e处理时在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());} 
    });