K
K
Konstantin2019-04-06 21:31:51
Java
Konstantin, 2019-04-06 21:31:51

How to do a countdown in java swing?

I wrote a small program in java using swing. In one place, the program should print in jTextfield a countdown of seconds from 3 to 0, then a start message. I tried with the following construction:
for(int i = 3, i > o; i--)
{ jTextfield.setText("Remaining: " + i);
Thread.sleep(1000);
}

All this was assigned inside jButton, i.e. when clicking the jButton with the mouse. In short, the whole program hung for these very 3 seconds, and then 1 came out in jTextfield, and that's it. I also tried with Timer and TimerTask, but it didn't work there either. How can I solve this problem, please help.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
S
Sergey Gornostaev, 2019-04-07
@Skelorc

When a window is created, an Event Dispatch Thread is created , inside which an infinite loop spins, at each iteration getting an event from the queue and launching a handler for it. It is useless to use cycles in the handler to change the interface, since all changes will simply queue up and will only be executed on one of the next iterations of the event loop. And even more so, you cannot stop the Event Processing Thread (which you do by calling Thread.sleep(1000)), this will freeze the entire application. Therefore, it is necessary to use the mechanisms offered by the library for launching background tasks and interacting with them. For example, such as SwingUtilities.invokeLater() , Timer and 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();
    }
}

A
alfss, 2019-04-06
@alfss

Need a separate thread for the timer

S
sergey, 2019-04-06
kuzmin @sergueik

need npr tk

public void mouseReleased(MouseEvent mouseEvent) {
        if (SwingUtilities.isLeftMouseButton(mouseEvent)) {
          System.out.println("Left button released.");
          System.err.println("Counting down from " + i);

          // NOTE: SwingUtilities.invokeLater shows only the last update of the
          // text
          // SwingUtilities.invokeLater(new Runnable() {
          // });
          Runnable r = new Runnable() {
            @Override
            public void run() {
              final int progress = i;
              for (int cnt = progress; cnt > 0; cnt--) {
                final int current = cnt;
                String buttonText = String.format("Calculated %d of %d",
                    current, progress);
                button.setVisible(false);
                button.setText(buttonText);
                button.doLayout();
                button.setVisible(true);
                System.err.println("updated butto text to " + buttonText);
                try {
                  Thread.sleep(300);
                } catch (InterruptedException e) {
                  System.err.println("Exception (ignored): " + e.toString());
                }
              }
            }
          };
          Thread t = new Thread(r);
          t.start();
        }

numerous reassignments - experimented with invokeLater - clean up the pl itself

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question