0

I have a mulitpanel frame that serves different display purposes, one of them is used to show a time countdown string which excuted by a scheduled timetask:

private class TimerPad extends JPanel {

    private int timeLeft = 60;
    private String prefix = "Time Left: ";

    TimerPad() {
        setDoubleBuffered(true);
    }

    public void start() {
        new java.util.Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                if (gameStatus == BoardStatus.JUDGING) {
                    this.cancel();
                } else if (timeLeft == 0) {
                    submitCards(cardsSouth);
                    this.cancel();
                } else {
                    timeLeft--;
                    repaint();
                }
            }
        }, 1000, 1000);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
          .....
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(240, 50);
    }
} 

This panel is added in the main frame, and its start() method triggered when it externally requested. Now the timePad only seems to be faring fine if the normal 60 secs elapsed, but when I use a button(i.e. submit) try to cancel the task earlier all the GUI are frozen ... I tried to wrap a runner for the task but it turned out the same...

James Dunn
  • 8,064
  • 13
  • 53
  • 87
Saintor
  • 1
  • 3
  • 2
    You should be using [javax.swing.Timer](http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html) instead of the general purpose `java.util.Timer` to avoid violating swing threading rules. – kiheru Aug 29 '13 at 14:02
  • there isn't too much components updates in this case, so both timer should serve the purpose (i just tried). It looked like after timer stopped(with button action), the owner frame lose the focus(rather than said frozen), and since i have another main modal frame opened there, i just can't get back the timepad owner.... – Saintor Aug 29 '13 at 15:06
  • 1
    `there isn't too much components updates in this case, so both timer should serve the purpose` - it has nothing to do with the number of components you are updates. Swing components should be updated on the EDT by using a Swing Timer. Yes, other Timers will work most of the time but you will have random problems and since you can't duplicate random problems you will waste an incredible amount of time trying to debug the problem. Read the Swing tutorial on [Concurrency](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html). – camickr Aug 29 '13 at 15:11
  • 1
    Please have a look at this wonderful answer, creation of [stopwatch](http://stackoverflow.com/a/2576909/1057230), by @trashgod. Use `javax.swing.Timer`, using this, all updates will happen on the `EDT`. For what you are using `java.util.Timer`, it becomes the duty of the programmer to put all GUI related updates on the `EDT`, which you are not doing anywhere. Moreover, `Swing` components use [Double Buffering](http://docs.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html) by default, there is no reason to call `setDoubleBuffered(true)`, on the instance of `JPanel` atleast :-) – nIcE cOw Aug 29 '13 at 15:34

0 Answers0