Java Swing Параллельный дисплей JTextArea - PullRequest
2 голосов
/ 15 декабря 2010

Мне нужно выполнить / отобразить серию событий от Arraylist до JTextArea, однако каждое событие выполняется с разным временем. Ниже приведен краткий пример моей цели:

public void start(ActionEvent e)
 {
  SwingUtilities.invokeLater(new Runnable()
  {
   public void run()

   {
    jTextArea.append("Test" + "\n");
    try
    {
     Thread.sleep(3000);
    } catch (InterruptedException e1)
    {
     e1.printStackTrace();
    }
    jTextArea.append("Test1" + "\n");
   }
  });
 }

Так что прямо сейчас «Test» и «Test1» отображаются в JTextArea после завершения всего выполнения. Как сделать так, чтобы сначала показывалось «Test», а затем через 3 секунды - «Test1»

Спасибо всем заранее

Ответы [ 3 ]

5 голосов
/ 15 декабря 2010

invokeLater планирует запуск для выполнения в потоке диспетчеризации событий.Вы не должны спать в этом, или вы будете голодать нить отправки.Попробуйте вместо этого использовать отдельный рабочий поток:

Thread worker = new Thread(new Runnable(){
    public void run(){
        jTextArea.append("Test" + "\n");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        jTextArea.append("Test1" + "\n");

    }
});
worker.start();
3 голосов
/ 16 декабря 2010

Если ваши задачи требуют много времени / ресурсов процессора, то да, для этого обязательно используйте фоновый поток, например объект SwingWorker или Runnable, запускаемый в потоке.Если, однако, вам нужно пошагово отобразить что-то, и все, что вам нужно, это Swing-эквивалент Thread.sleep (3000), тогда лучше всего использовать Swing Timer.Существует прекрасное руководство по их использованию, которое вы можете найти здесь: http://download.oracle.com/javase/tutorial/uiswing/misc/timer.html

Например:

 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import javax.swing.*;

 public class Fu extends JPanel {
      private static final int TIMER_DELAY = 600;
      protected static final int MAX_COUNT = 20;
      private JTextArea jTextArea = new JTextArea(10, 10);
      private JButton startBtn = new JButton("Start");
      private Timer timer;

      public Fu() {
           startBtn.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                     startAction(e);
                }
           });

           add(new JScrollPane(jTextArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 
                     JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
           add(startBtn);
      }

      private void startAction(ActionEvent e) {
           if (timer != null && timer.isRunning()) {
                // prevent multiple instances of timer from running at same time
                return;
           }
           timer = new Timer(TIMER_DELAY, new ActionListener() {
                private int count = 0;
                public void actionPerformed(ActionEvent e) {
                     if (count < MAX_COUNT) {
                          count++;
                          jTextArea.append("Test " + count + "\n");
                     } else {
                          jTextArea.append("Done! \n");
                          timer.stop();
                          timer = null;
                     }
                }
           });
           timer.setInitialDelay(0);
           timer.start();
      }

      public static void main(String[] args) {
           SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                     JFrame frame = new JFrame("Foo");
                     frame.getContentPane().add(new Fu());
                     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                     frame.pack();
                     frame.setLocationRelativeTo(null);
                     frame.setVisible(true);
                }
           });
      }
 }
2 голосов
/ 15 декабря 2010

Как уже отмечалось, это плохая идея, поскольку вы будете блокировать поток событий.

Однако важно понять причину этого.Как вы, похоже, знаете, весь код, который влияет на состояние компонентов Swing, должен происходить в потоке обработки событий (именно поэтому всегда следует использовать invokeLater и друзей).

Что немного менее лучшеИзвестно, что болевой код также выполняется в потоке обработки событий.Когда ваш вызов Thread.sleep выполняется, он не только блокирует поток событий, но также блокирует любое рисование компонентов.Вот почему полное обновление происходит за один раз - JTextArea обновляется, но его нельзя перекрашивать, пока не вернется ваш метод run.

Здесь доступно много информации: http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...