Question

I am doing a timer to countdown fro 90 seconds all the way down to zero, however when i run it, it will run for 1 second and terminate, plz help! Point out what is wrong!

package TestingFile;

import javax.swing.*;
import javax.swing.event.*;

import java.awt.*;
import java.awt.event.*;


public class TestingATimer extends JFrame
{
    private Timer timer;
    public int count = 90;

    public TestingATimer()
    {
        timer = new Timer(1000, new TimerListener());
        timer.start();
    }

    private class TimerListener implements ActionListener
    {
        public void actionPerformed (ActionEvent e)
        {
            if (count != 0)
            {   
            count--;
            System.out.println(count + " seconds elapsed"); 
            }
        }

    }

    public static void main (String [] args)
    {
        new TestingATimer ();
    }
}
Was it helpful?

Solution

The (Swing) Timer is likely using a daemon based thread. This means that once the main method exists, there is nothing keeping the JVM from terminating...

From the Thread JavaDocs

When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class). The Java Virtual Machine continues to execute threads until either of the following occurs:

  • The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
  • All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.

So there is nothing stopping the JVM from terminating.

The question is, why are you using a javax.swing.Timer without a GUI? What are you trying to achieve?

Updated

If you don't want to use a GUI, you will need to use a java.util.Timer, for example...

import java.util.Timer;
import java.util.TimerTask;

public class Clock {

    private static Timer timer;

    public static void main(String[] args) {

        timer = new Timer();
        timer.scheduleAtFixedRate(new TickTask(), 0, 1000);

    }

    public static class TickTask extends TimerTask {

        private boolean started = false;
        private long startTime = 0;

        @Override
        public void run() {
            if (!started) {
                started = true;
                startTime = System.currentTimeMillis();
            } else {
                long dif = System.currentTimeMillis() - startTime;
                long seconds = dif / 1000;
                System.out.println(seconds);
                if (seconds >= 90) {
                    timer.cancel();
                }
            }
        }

    }

}

Otherwise you'll need to supply some kind GUI...

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ClockGUI {

    public static void main(String[] args) {
        new ClockGUI();
    }

    public ClockGUI() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Timer timer;
        private JLabel clock;

        public TestPane() {
            setLayout(new GridBagLayout());
            clock = new JLabel("...");
            add(clock);
            timer = new Timer(1000, new ActionListener() {

                private boolean started = false;
                private long startTime = 0;

                @Override
                public void actionPerformed(ActionEvent e) {
                    if (!started) {
                        started = true;
                        startTime = System.currentTimeMillis();
                    } else {
                        long dif = System.currentTimeMillis() - startTime;
                        long seconds = dif / 1000;
                        clock.setText(Long.toString(seconds));
                        if (seconds >= 90) {
                            timer.stop();
                        }
                    }
                }
            });
            timer.start();
        }

    }

}

OTHER TIPS

" however when i run it, it will run for 1 second and terminate"

Because you've set it to 1 second (1000 miliseconds) here:

timer = new Timer(1000, new TimerListener());

If you want 90 seconds then do this:

timer = new Timer(90000, new TimerListener());
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top