Отображение текста в JTextArea при расчете - PullRequest
2 голосов
/ 22 мая 2011

Приложение, которое я пишу, состоит, среди прочего, из JButton и JTextArea. Нажатие на кнопку приводит к длинным вычислениям, в результате чего текст отображается в JTextArea. Несмотря на то, что расчет длинный, у меня могут быть средние результаты на ходу (например, приложение, которое приблизительно равно пи до 100 цифр - каждые несколько секунд я могу написать еще одну цифру). Проблема в том, что даже если я напишу (находясь в классе ActionListener, потому что кнопка вызвала вычисление), чтобы установить для текста JTextArea что-то, он не будет отображаться, пока вычисление выполнено, и я вижу только конец результат после окончания расчета.

Почему это так, и как я могу это исправить?

Заранее спасибо.

Ответы [ 2 ]

5 голосов
/ 22 мая 2011

Ваша проблема в том, что вы выполняете долгий расчет в основном потоке Swing, EDT, и это заморозит весь ваш графический интерфейс, пока процесс не завершится сам. Решение состоит в том, чтобы использовать фоновый поток для своих расчетов, и простой способ сделать это - использовать SwingWorker для создания фона потока для основного потока Swing, EDT, и опубликовать / обработать промежуточные результаты в JTextArea. Подробнее о SwingWorkers и EDT см. Здесь: Параллелизм в Swing

Кроме того, если вы предоставите приличную sscce , мы, вероятно, сможем дать вам более подробный ответ, возможно, даже с примером кода.

Пример SSCCE:

import java.awt.event.*;
import java.text.DecimalFormat;
import java.util.List;
import javax.swing.*;

public class InterimCalc {
   private JPanel mainPanel = new JPanel();
   private JTextField resultField = new JTextField(10);
   private JButton doItBtn = new JButton("Do It!");
   private DecimalFormat dblFormat = new DecimalFormat("0.0000000000");
   private SwingWorker<Void, Double> mySwingWorker = null;

   public InterimCalc() {
      mainPanel.add(doItBtn);
      mainPanel.add(resultField);
      displayResult(0.0);

      doItBtn.addActionListener(new DoItListener());
   }

   public void displayResult(double result) {
      resultField.setText(dblFormat.format(result));
   }

   public JPanel getMainPanel() {
      return mainPanel;
   }

   private class DoItListener implements ActionListener {

      public void actionPerformed(ActionEvent e) {
         if (mySwingWorker != null && !mySwingWorker.isDone()) {
            mySwingWorker.cancel(true);
         }
         displayResult(0.0);
         mySwingWorker = new MySwingWorker();
         mySwingWorker.execute();
      }
   }

   private class MySwingWorker extends SwingWorker<Void, Double> {

      private static final int INTERIM_LENGTH = 10000; // how many loops to do before displaying

      @Override
      protected Void doInBackground() throws Exception {
         boolean keepGoing = true;
         long index = 1L;
         double value = 0.0;
         while (keepGoing) {
            for (int i = 0; i < INTERIM_LENGTH; i++) {
               int multiplier = (index % 2 == 0) ? -1 : 1;
               value += (double)multiplier / (index);
               index++;
            }
            publish(value);
         }
         return null;
      }

      @Override
      protected void process(List<Double> chunks) {
         for (Double dbl : chunks) {
            displayResult(dbl);
         }
      }

   }

   private static void createAndShowUI() {
      JFrame frame = new JFrame("Decay Const");
      frame.getContentPane().add(new InterimCalc().getMainPanel());
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}
0 голосов
/ 23 мая 2011

Вы также можете отобразить какой-нибудь вращающийся GIF или «индикатор выполнения», чтобы показать, что ответ рассчитывается; обратная связь с пользователем хорошая.

(как только вы используете свингворк, графический интерфейс не зависает, и графический интерфейс может выполнять свои функции во время вычисления)

...