Trung Nguyen
Trung Nguyen

Reputation: 457

Implement StopWatch

Could anyone explain why my start/stop button doesn't work please? This is not a full implemented StopWatch but I got stuck here. Any help is appreciated! This is my first time posting question in forum so if there is any problem in my post, please tell me. This is my code:

public class StopWatch {

    private static boolean tiktok;

    public static void setGo(boolean go) {
        tiktok = go;
    }

    public static void main(String[] args) {
        int counter = 0;
        StopWatch stop = new StopWatch();
        ClockFrame window = new ClockFrame("StopWatch");
        JLabel lb = window.init();
        while (true) {
            lb.setText(Integer.toString(counter++));
            if (counter == 61) {
                counter = 0;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
            }
        }
    }

}

class ClockFrame extends JFrame {
    JLabel hour, minus, sec;

    public ClockFrame(String title) {
        super(title);
    }

    JLabel init() {
        JFrame frame = new JFrame("Stop Watch");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel time = new JPanel();
        hour = new JLabel("0");
        minus = new JLabel("0");
        sec = new JLabel("0");
        time.add(hour);
        time.add(minus);
        time.add(sec);

        JPanel pane = new JPanel();
        pane.setLayout(new FlowLayout());
        JButton start = new JButton("Start");
        start.addActionListener(new startstopActionListener(true));
        JButton stop = new JButton("Stop");
        stop.addActionListener(new startstopActionListener(false));
        JButton reset = new JButton("Reset");
        pane.add(start);
        pane.add(stop);
        pane.add(reset);

        Container window = frame.getContentPane();
        window.setLayout(new GridLayout(2, 1));
        window.add(pane);
        window.add(time);

        frame.setSize(500, 200);
        frame.setVisible(true);
        return sec;
    }
}

class startstopActionListener implements ActionListener {

    private boolean b;

    public startstopActionListener(boolean b) {
        this.b = b;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        StopWatch.setGo(b);
    }
}

Upvotes: 0

Views: 739

Answers (2)

Robin
Robin

Reputation: 36611

If you want to make stopwatch in Swing, you best take a look at the javax.swing.Timer class. It makes it very easy to periodically update a Swing component (in your case a JLabel). Using the Timer avoids the Thread.sleep call, which you should never call on the Event Dispatch Thread as it blocks the UI.

JB Nizet already provided a link to Swing concurrency tutorial. I would suggest you also take a look at the links provided in the Swing concurrency section of the 'Swing info page' of this site, and my answer on a related question.

Upvotes: 3

JB Nizet
JB Nizet

Reputation: 691715

You don't respect Swing's threading policy:

  1. Swing components should only be used from the event dispatch thread
  2. Long-running and blocking methods (such as the one with the infinite loop updating the label) should be run out of the event dispatch thread (but the update of the label must be made in the EDT - see rule 1)

Read the Swing tutorial about concurrency.

Upvotes: 3

Related Questions