使用SwingWorker更新Java Gui

时间:2012-05-08 18:24:35

标签: java user-interface jtextarea swingworker jprogressbar

下面是一个没有像我预期的那样更新Java GUI的SwingWorker实例。

SwingWorker是在按钮的动作侦听器中实现的。定义循环的minmax都是“final int”,它们是动作侦听器的本地。

SwingWorker应该在每次迭代时调用NQueens对象的go()方法,该方法递归地找到n-queens的所有解。然后调用NQueens对象的toString(),之后发布String,以便process()方法更新jProgressBarjTextArea。但是按下按钮时没有任何反应。这是我应该如何实现一个加上GUI组件更新的密集过程?

new SwingWorker <Void,String>()
{       
     private int totalPercent;
     @Override
     protected Void doInBackground()
     {
         int diff = max - min + 1;
         int percent = 100;
         if(diff != 0)
         {
              percent = 100/diff;
         }
         totalPercent = 0;
         NQueens queens = new NQueens(min);
         for(int j = min; j <= max; j++)
         {
              queens.go();
              totalPercent += percent;
              String newText = queens.toString();
              publish(newText);
              queens.nextSet();
         }

         isCalced = true;

         return null;
      }

      protected void process(String results)
      {
           jTextArea2.append(results);
           jProgressBar1.setValue(totalPercent);
           jProgressBar1.repaint();
      }                                 
  }.execute();  

1 个答案:

答案 0 :(得分:0)

原因可能是您没有实施正确的流程方法?我相信过程的正确签名是

process(List<String> results) {
  for(String result : results) {
    jTextArea2.append(result);
  }
}

关于更新进度条; doInBackground方法在单独的线程中运行,而进程方法在您调用worker的线程上运行。您不应该从doInBackground写入totalPercent变量并从process()读取它。有关详情,请参阅thread visibility。相反,创建一个名为ProgressUpdateEvent的类,它可以保存百分比值和消息。这样,你可以这样做:

new SwingWorker <Void,ProgressUpdateEvent>() {

  protected Void doInBackground() {
    for (int i = 0; i <= 100; i++) {
      publish(new ProgressUpdateEvent("At " + i + "% right now", i);
    }
  }

  protected void process(List<ProgressUpdateEvent> events) {
    for (ProgressUpdateEvent event : events) {
      jTextArea2.append(event.getMessage());
      jProgressBar1.setValue(event.getPercent());
    }
  }
}