Как позвонить в Swing Timer изнутри JButton - PullRequest
2 голосов
/ 22 октября 2019

Я пытаюсь запустить таймер после нажатия кнопки.

Следующий код без кнопки работает

    Timer timer = new Timer(1000, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            System.out.println("test");
        }
    });
    timer.start();
    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

Однако, когда я помещаю его в кнопку

    startButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
            Timer timer = new Timer(1000, new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    System.out.println("test");
                }
            });
            timer.start();
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });

Он ничего не печатает при нажатии кнопки.

Я думал, что это произошло, потому что основной поток заканчивается, поэтому я попытался добавить while (true) в конце, но это не изменилосьчто угодно.

Спасибо

1 Ответ

1 голос
/ 22 октября 2019

Избавьтесь от Thread.sleep(10000);, это приводит к тому, что поток диспетчеризации событий переходит в спящий режим на 10 секунд, что останавливает его от обработки очереди событий, в которой Timer будет публиковать свои события "действия" для запуска * 1003. *

Взгляните на В ветке рассылки событий для получения более подробной информации

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Test {

    public static void main(String[] args) throws IOException {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            JButton btn = new JButton("Start");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    Timer timer = new Timer(1000, new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent arg0) {
                            System.out.println("...");
                        }
                    });
                    timer.start();
                }
            });
            add(btn);
        }

    }


}

но как мне остановить ее через определенное время?

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

Во-вторых, вы можете использовать секунду Timer, установить указанное время ожидания (и не повторять) и когдаОгонь, остановите первый Timer или используйте что-то вроде Instant, чтобы вычислить разницу между тем, когда таймер был запущен и сейчас, для пример и пример (чтобывторая половина)

...