0

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

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

SwingWorker 应该在每次迭代时调用NQueens对象的 go() 方法,该方法递归地找到 n-queens 的所有解决方案。然后调用NQueens对象的,然后toString()发布字符串,以便 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();  
4

1 回答 1

0

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

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

关于更新进度条;doInBackground 方法在单独的线程中运行,而 process 方法在您调用 worker 的线程上运行。您不应该从 doInBackground 写入 totalPercent 变量并从 process() 读取它。有关更多信息,请参阅线程可见性。相反,创建一个名为 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());
    }
  }
}
于 2012-06-07T06:46:44.547 回答