Your program appears to be a Swing or AWT GUI program, and if so, you're using the wrong type of Timer, here a java.util.Timer and java.util.TimerTask, both of which are not Swing thread safe. This can cause your GUI to freeze, and the numbers not show up, just as you're seeing. Instead use a timer built specifically for these GUI's, a Swing Timer (click on this link for the tutorial). You're also calling the timer from the drawing code which is the exact opposite of what you should be doing. Instead the Timer should change the state of your counting variable and then call repaint(). The drawing code then gets the value of the counting variable and displays it within the GUI.
For example, your Swing Timer could use an ActionListener whose actionPerformed method looks something like this:
public void actionPerformed(ActionEvent e) {
if (counter != 0) {
// if the counter hasn't reached the end
counter--; // reduce counter by one
repaint(); // tell the GUI to repaint
} else {
timer.stop(); // otherwise at the end, so stop the timer
countDownAction.setEnabled(true); // and re-enable the button
}
}
A complete GUI example could look like this:
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
@SuppressWarnings("serial")
public class CountDown extends JPanel {
public static final int TIMER_DLEAY = 1000;
private static final Font COUNTER_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 400);
private static final int TEXT_X = 200;
private static final int TEXT_Y = 500;
private int counter;
private JSpinner spinner = new JSpinner(new SpinnerNumberModel(5, 0, 20, 1));
private CountDownAction countDownAction = new CountDownAction("Count Down");
private JButton countDownButton = new JButton(countDownAction);
private Timer timer;
public CountDown() {
setPreferredSize(new Dimension(800, 600));
add(new JLabel("Starting Value:"));
add(spinner);
add(countDownButton);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.setFont(COUNTER_FONT);
String text = String.format("%02d", counter);
g.drawString(text, TEXT_X, TEXT_Y);
}
private class CountDownAction extends AbstractAction {
public CountDownAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
// inactivate the button/action
countDownAction.setEnabled(false);
counter = (int) spinner.getValue();
repaint();
timer = new Timer(TIMER_DLEAY, new TimerListener());
timer.start();
}
}
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (counter != 0) {
// if the counter hasn't reached the end
counter--; // reduce counter by one
repaint(); // tell the GUI to repaint
} else {
timer.stop(); // otherwise at the end, so stop the timer
countDownAction.setEnabled(true); // and re-enable the button
}
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("CountDown");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new CountDown());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
countdown()method and it counted down to 0 in 1-second intervals. I don't see how thedraw()method is relevant to the question. - shmosel