Как сделать обратный отсчет времени в java swing?

123
13 января 2020, 05:10

Написал небольшую программу в java используя swing. В одном месте, программа должна выводить в jTextfield отсчет секунд от 3 до 0, затем сообщение старт. Пытался с помощью такой конструкции:

for(int i = 3, i > o; i--)
{ jTextfield.setText("Осталось: " + i);
Thread.sleep(1000);
 }

Все это приписывалось внутри jButton, т.е. при нажатии мышкой на кнопку jButton. Короче, вся программа висела эти самые 3 секунды, а потом в jTextfield вышло 1, и все на этом. Также пытался с Timer и TimerTask, но там тоже не срослось. Как мне решить эту проблему, помогите а.

Answer 1

При создании окна создаётся Event Dispatch Thread, внутри которого крутится бесконечный цикл, на каждой итерации достающий событие из очереди и запускающий обработчик для него. В обработчике бесполезно использовать циклы для изменения интерфейса, так как все изменения просто встанут в очередь и будут выполнены только на одной из следующих итераций цикла событий. И тем более нельзя останавливать Поток Обработки Событий (что вы делаете вызовом Thread.sleep(1000)), это заморозит всё приложение. Поэтому необходимо использовать предлагаемые библиотекой механизмы запуска фоновых задач и взаимодействия с ними. Например такие, как SwingUtilities.invokeLater(), Timer и SwingWorker.

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.Timer;
public class Countdown {
    private final JLabel label = new JLabel("...");
    private final JButton button = new JButton("Click me");
    private final Timer timer;
    private int count = 3;
    public Countdown() {
        timer = new Timer(1000, e -> {
            if (count > 0) {
                label.setText(String.valueOf(count--));
            } else {
                ((Timer) (e.getSource())).stop();
                count = 3;
                button.setEnabled(true);
            }
        });
        timer.setInitialDelay(0);
        button.addActionListener(e -> {
            timer.start();
            button.setEnabled(false);
        });
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        frame.add(label, BorderLayout.PAGE_START);
        frame.add(button, BorderLayout.PAGE_END);
        frame.pack();
        frame.setVisible(true);
    }
    public static void main(String[] args) {
        new Countdown();
    }
}
READ ALSO
Как отсортировать коллекцию HashMap? [закрыт]

Как отсортировать коллекцию HashMap? [закрыт]

Хотите улучшить этот вопрос? Переформулируйте вопрос, чтобы он соответствовал тематике «Stack Overflow на русском»

155
Как вызвать два метода подряд через точку?

Как вызвать два метода подряд через точку?

есть класс myDateКак сделать так, чтобы я мог вызывать методы следующим образом: myDate

147
Как работать с SOAP веб-сервисом из Java?

Как работать с SOAP веб-сервисом из Java?

Достаньте из http://webservicesoorsprong

153
XMLPullParser обрезал последний элемент(ImageView)

XMLPullParser обрезал последний элемент(ImageView)

XMLPullParser обрезает последний элемент

121