我怎样才能在 JTextArea 中完成进度显示,同时 运行 代码确定要在该 JTextArea 中显示什么?

How can I make a progress complete show in a JTextArea while running code that's figuring out what to display in that JTextArea?

我不知道这是否可能。我正在制作一个彩票应用程序,我正在尝试使用尽可能少的 GUI 组件。所以我有一个 JTextArea 应该显示以下消息(例如):

“正在计算...55.4%”

当我将它打印到控制台时,它显示得很好,但它不会将它打印到 JTextArea。我尝试使用 SwingUtilities.invokeLater 但这也不起作用。

    for (int x = 0; x < daysBetween; x++)
    {
      completion = "Calculating..." + df.format((100 * (x + 1)) / daysBetween) + "%";
      if (!textArea.getText().equals(completion))
      {
        textArea.setText(completion);
      }
      /*
      Here I have a lot of irrelevant code that compares your tickets to the winning tickets and counts your winnings and other statistics...
      */
    }

    ticketReport += "Computation time: " + getElapsedTime(start, System.nanoTime());
    ticketReport += "\nEnd date: " + (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DAY_OF_MONTH) + "/" + cal.get(Calendar.YEAR); 
    ticketReport += "\nTotal # of tickets purchased: " + numOfTicketsPurchased;
    /*
    etc. with filling out the ticket report
    */
    textArea.setText(ticketReport);

如您所料,我希望在上面的 for 循环中设置 textArea 的文本时更新 JTextArea。它直到方法结束时才更新 JTextArea,这是我设置文本区域以显示工单报告时的最底部。

我的最终目标:我想最终把它变成一个 Android phone 应用程序,所以这就是我不想使用任何弹出窗口或任何东西的原因。

/* 编辑:这暂时解决了问题,但我 运行 陷入了另一个问题。现在,当我尝试通过调用带有参数 true 的取消方法来取消 SwingWorker 时,它不会取消。请参阅我的其他答案以了解我解决此问题的方式。 */

我明白了。上面的方法我放在了一个SwingWorker里面,如下:

      SwingWorker<Void, Void> sw = new SwingWorker<Void, Void>()
      {
        @Override
        protected Void doInBackground() throws Exception
        {
          //method here
        }
      }

在该方法中,我使用参数“(100 * (x + 1)) / daysBetween”调用了 setProgress 方法以显示正确的完成百分比。然后在那之后,我添加了这个:

      sw.execute();
      sw.addPropertyChangeListener(new PropertyChangeListener()
      {
        @Override
        public void propertyChange(PropertyChangeEvent arg0)
        {
          textArea.setText("Calculating..." + sw.getProgress() + "%");
          if (sw.getProgress() == 100)
            textArea.setText(ticketReport);
        }
      });

它将百分比显示为整数而不是我最初想要的#.##,但如果我愿意,我可以很容易地更改它。

我最初的 SwingWorker 方法使它在 JTextArea 中显示完成百分比状态。我添加了一个取消操作的选项,当我尝试取消时,"thread" (SwingWorker) 不会取消。当我取消并重新启动时,它会不断堆叠。每次连续开始而另一个正在运行都会导致计算速度越来越慢,然后给出不正确的信息。

我第二次这样做的方式解决了原来的问题和这个新问题。我创建了一个扩展 Thread 的新私有 class,超越了它的 运行() 方法,并在该方法中插入了要在线程中执行的代码。我注意到任何停止线程的方法都因为潜在问题而被弃用,所以我创建了一个布尔值,当用户请求停止线程时设置它,并且在线程内部它定期读取布尔值,然后在它等于时退出为真。

我启动线程的方式是重新初始化对象 BackgroundCalc 并调用它的 start() 方法。

  private class BackgroundCalc extends Thread
  {
    public void run()
    {
      /*
      initializing stuff here
      */
      for (int x = 0; x < daysBetween; x++)
      {
        progress = (100 * (x + 1)) / daysBetween;
        if (destroyCalcThread) return;
        /*
        background calculations here
        */
      }
      /*
      finish up thread here
      */
    }
  }

我对线程有点缺乏经验,所以希望我在这里的挣扎以及我解释它的方式能帮助那些对这个概念缺乏经验的人。