Синхронизация таймера свинга

1

Я смущен тем, как работает таймер Swing. В приведенном ниже коде я хочу отображать от 0 ~ 9 каждые 400 мс в первом текстовом поле, когда нажимаем START (один раз). После этого второе текстовое поле отобразит "Готово".

Изображение 174551

public class Main extends JPanel{

private static final long serialVersionUID = 1L;
private JButton bStart;
private JTextField tTest;
private JTextField tNumber;

Main(){
    bStart = new JButton("Start");
    bStart.addActionListener(new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            displayNumbers();
        }       
    });

    tTest = new JTextField(null, 30);
    tNumber = new JTextField(" ", 30);
    tNumber.setEditable(false);
    this.setSize(300, 100);
    this.add(bStart);
    this.add(tNumber);
    this.add(tTest);

}

public void displayNumbers(){
    new Timer(400, new ActionListener() {
        int i = 0;
        public void actionPerformed(ActionEvent evt) {
            if(i<10){
                tNumber.setText(Integer.toString(i));
                i++;
            }       
            else
                ((Timer)evt.getSource()).stop();
        }
    }).start(); 

    tTest.setText("Finished");
}

public static void createAndShowGUI(){
    JFrame frame = new JFrame("test");
    frame.add(new Main());
    frame.setSize(400, 150);
    frame.setVisible(true); 
}


public static void main(String args[]){
    SwingUtilities.invokeLater(new Runnable(){
        @Override
        public void run() {
            // TODO Auto-generated method stub
            createAndShowGUI();
        }           
    });     
}
}

Однако сначала он отображает "Готово" до окончания отображения 0 ~ 9. Я думаю, что таймер Swing работает также в EDT, поэтому "tTest.setText(" Готово "); будет выполняться после потока таймера. Почему это не работает? Как подождать окончания отображения 0 ~ 9, а затем распечатать "Готово"? Благодарю!

Спасибо за ваши ответы. На самом деле то, что я хочу спросить, в общем:

new Timer(delay, new ActionListener() {

    public void actionPerformed(ActionEvent evt) {
            doSomething();
    }

}).start(); 

    doOthers();

Как разрешить doOthers() выполнить после doSomething()? (В некоторых случаях мы не можем поместить doOthers() внутри actionPerformed функции, как упоминалось в некоторых ответах).

Теги:
multithreading
timer
swing
synchronization

1 ответ

6

Таймер работает одновременно. Таким образом, таймер запускается, затем текст завершается, а затем срабатывает таймер и появляется первое число.

Чтобы завершить отображение таймера после его завершения, поместите tTest.setText("Finished"); в предложении else if(i<10).

  • 1
    И используйте брекеты!
  • 1
    Чтобы уточнить, timer.start() не блокирует выполнение кода, поэтому setText("Finished") вызывается сразу.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню