2

我知道这里有很多JProgressBar问题,但是通过所有答案,我似乎无法诊断出我的问题。我正在使用一些地址验证软件处理文件。我单击“处理”按钮,我需要JProgressBar更新处理的每个文件。这是按钮:

private JButton getJButton0() {
...
   jButton0.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
         jButton0ActionActionPerformed(event);
         t.start();
      }
...

根据大家的建议,我setValue()在一个线程中使用了该方法

Thread t = new Thread(){
    public void run() {
    SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        jProgressBar0.setValue(BulkProcessor.getPercentComplete());
    }
});
try {
    Thread.sleep(100);
} catch (InterruptedException e) {
}
...

BulkProcessor.getPercentComplete()是我从另一个代表完成百分比的类调用的方法。我已经测试了这个方法,它可以正确更新。问题是进度条在文件完成处理之前不会更新,然后会跳转到 100%。如果这是一个重复的问题,我深表歉意,但我在这个网站上做了一些认真的挖掘,但没有运气。非常感谢任何帮助。

编辑:

每个推荐的副本,我试过这个:

public void update(){
   new SwingWorker<Void,Void>() {
   protected Void doInBackground() throws Exception {
   jProgressBar0.setValue(BulkProcessor.getPercentComplete());
   return null;
 };
 }.execute();
}

然后尝试在(用actionPerformed()切换)下调用这个 update() 方法。我仍然有同样的问题。t.start()update()

编辑

根据 user1676075 的建议,但同样的问题:

    public static void update(){
       new SwingWorker<Void,Integer>() {
       protected Void doInBackground() throws Exception {
           do
           {
           percentComplete = BulkProcessor.getPercentComplete();
           publish(percentComplete);
           Thread.sleep(100);
           } while(percentComplete < 100);

        return null;
       }
       @Override
    protected
       void process(List<Integer> progress)
       {
           jProgressBar0.setValue(progress.get(0));
       }
     }.execute();
   }

编辑

这是我BulkProcessor班上的代码

 private String getOutputLine( String searchString, String inputLine )
throws QasException
{
 ..(code for processing lines)..
 countRecord++;
    percentComplete = (int) Math.round((countRecord/totalRecord)*100);

totalRecordBulkProcessor在我班的主班更新

 public static void main( String input, String output ){
    count.clear();
    try{
        String inputFile = input;
        String outputFile = output;
        LineNumberReader  lnr = new LineNumberReader(new FileReader(new File(input)));
        lnr.skip(Long.MAX_VALUE);
        totalRecord = lnr.getLineNumber() + 1; //line count in file
        BulkProcessor bulk = new BulkProcessor(inputFile, outputFile, ConfigManager.DFLT_NAME);
        bulk.process();
    }catch(Exception e ){
        e.printStackTrace();
    }

}
4

4 回答 4

0

您是否尝试过使用PropertyChangeListener接口?

计算将由 Swingworker-thread 完成,main-gui 将实现此接口。一些示例代码

@Override
public void actionPerformed(ActionEvent e) {
    this.myButton.setEnabled(false);
    MyWorkerThread thread = new MyWorkerThread(); //Data-processing
    thread.addPropertyChangeListener(this.mainguiframe); //Separation of concern
    thread.execute();
}

使用 swing-worker-thread 的“setProgress”方法,如果发生了某些事情,将通知 main-gui-thread。

@Override
public void propertyChange(PropertyChangeEvent property) {
     Integer currentValue = new Integer(0);
     currentValue = (Integer) property.getNewValue();
     this.progressBar.setValue(currentValue.intValue());
}

Swing 不是线程安全的。这不是最好的解决方案,但也许它可以帮助您。如果有什么可怕的错误,请发表评论。

于 2013-06-24T22:16:34.823 回答
0

您可能犯的错误是调用 t.start(); 之后,jButton0ActionPerformed(event);这使得在执行操作后线程将启动。因此,进度条的值不会按预期更新。

您需要在 jButton0ActionPerformed(event); 中启动线程;然后更新其中的值。

于 2013-06-23T08:52:07.793 回答
0

只是预感,但是...

    percentComplete = (int) Math.round((countRecord/totalRecord)*100);

你确定这不是整数算术吗?我不知道 的类型totalRecord,所以我不能肯定。

我猜一切正常,只是进度一直是 0,直到完成,它神奇地是 100。这是因为一个 int 除以一个 int 不会有小数值(即 99/100 == 0, 100/100 == 1)。这完全符合您正在经历的症状。

尝试将上面的行替换为:

   percentComplete = (int) Math.round((countRecord/(double) totalRecord)*100);

看到它我是对的。:-)

于 2013-06-24T14:35:23.743 回答
0

看起来你正在混合使用。请参阅 SwingWorker 文档,顶部示例: http: //docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html

理想情况下,您应该在 SwingWorker 的 doInBackground 方法中更新 BulkProcessor,这将调用 setProgress,并且 jProgressBar 将像示例中那样监听这些进度更新。

如果这对您不起作用,它似乎不仅仅基于上述内容,请从按钮按下事件启动 SwingWorker。实现 SwingWorker 方法有点像这样(伪代码):

new SwingWorker<Void,Integer>()
{
  doInBackground()
  {
    do
    {
      percentComplete = BulkProcessor.getPercentComplete();
      publish(percentCompete);
      Thread.sleep(100);
    } while (percentComplete < 100);
  }

  @Override
  process(List<Integer> progress)
  {
     jProgressBar0.setValue(progress.get(0));
  }
}.execute();

您需要添加错误处理并检查完整和失败的情况,但这应该可以帮助您开始并到达您想要的位置。doInBackground 在后台线程中运行,因此不会阻塞任何内容,并且 process() 在 swing 工作线程上运行,因此将发布更新。

于 2013-06-17T20:08:37.320 回答