0

I am trying to make a stopwatch using swing, but it is not working. Here is my code. The Jlabel clock is always displaying -1, which should only happen if it is stopped. Am I using the invokelater properly?

import javax.swing.*;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;



public class sidePanel extends JApplet implements ActionListener{
    JPanel pane;
    JLabel clock;
    JButton toggle;

    Timer timer;
    StopWatch stopWatch;


    public void init()
    {
        pane = new JPanel();
        pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));

        clock = new JLabel("00:00");

        toggle = new JButton("Start/Stop");
        toggle.addActionListener(this);

        pane.add(clock);
        pane.add(toggle);


        timer = new Timer(500, this);
        timer.setRepeats(true);

        stopWatch = new StopWatch();



        add(pane);

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == toggle)
        {


            if(timer.isRunning())
            {
                stopWatch.endTime = System.currentTimeMillis();
                timer.stop();
            }
            else
            {
                stopWatch.startTime = System.currentTimeMillis();
                timer.start();
            }
        }

        if(e.getSource() == timer)
        {
            long time = stopWatch.getElapsedTime();
            sidePanel.this.clock.setText(String.valueOf(time));
        }
    }




    private class StopWatch{

        private long startTime =0;
        private long endTime =0;
        public boolean isRunning = false;


        public void start(){
            startTime = System.currentTimeMillis();
            isRunning = true;
        }

        public void end(){
            endTime = System.currentTimeMillis();
            isRunning = false;
        }

        public long getElapsedTime()
        {
            long currentTime = System.currentTimeMillis();
            if(isRunning)
                return (currentTime - startTime)/1000;
            else
                return -1;
        }

    }






}

Working code

import javax.swing.*;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;



public class sidePanel extends JApplet implements ActionListener{
    JPanel pane;
    JLabel clock;
    JButton toggle;

    Timer timer;
    //StopWatch stopWatch;

    boolean pressed = false;

    long startTime =0;
    long endTime =0;


    public void init()
    {
        pane = new JPanel();
        pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));

        clock = new JLabel("00:00");

        toggle = new JButton("Start/Stop");
        toggle.addActionListener(this);

        pane.add(clock);
        pane.add(toggle);


        timer = new Timer(500, this);
        timer.setRepeats(true);

        //stopWatch = new StopWatch();



        add(pane);

    }

    long cur;
    long end;
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == toggle)
        {

            if(!pressed)
            {
                timer.start();
                startTime = System.currentTimeMillis();
                pressed = true;
            }
            else
            {
                timer.stop();

                pressed = false;
            }
        }



            if(timer.isRunning())
            {
                endTime = System.currentTimeMillis();
                clock.setText(String.valueOf((endTime-startTime)/1000));

            }

    }

}
2
  • I think you need timer to update your time after certain delay. Commented Dec 15, 2012 at 0:19
  • Your thread doesn't loop at all. It updates the label time once and then exits. Also, why don't you use a javax.swing.Timer? Commented Dec 15, 2012 at 0:21

1 Answer 1

4

Your StopWatch class run once and then terminates...

public void run() {
    // Start here
    SwingUtilities.invokeLater(new Runnable()
    {
        @Override
        public void run() {
            long time = getElapsedTime();
            sidePanel.this.clock.setText(String.valueOf(time));
        }
    });
    // End here...
}

A thread will terminate when it exists it's run method, in this case, your StopWatch's run method.

What you need to do to is maintain a loop until the isRunning becomes false

public void run() {
    while (isRunning) {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run() {
                long time = getElapsedTime();
                sidePanel.this.clock.setText(String.valueOf(time));
            }
        });
        // Because we really don't want to bombboard the Event dispatching thread
        // With lots of updates, which probably won't get rendered any way,
        // We put in a small delay...

        // This day represents "about" a second accuracy...
        try {
            Thread.sleep(500);
        } catch (Exception exp) {
        }
    }
}

It would much simpler to use a javax.swing.Timer though...

private Timer timer;
public void init()
{
    pane = new JPanel();
    pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));

    clock = new JLabel("00:00");

    toggle = new JButton("Start/Stop");
    toggle.addActionListener(this);

    pane.add(clock);
    pane.add(toggle);

    timer = new Timer(500, new ActionListener() { 
        public void actionPerformed(ActionEvent evt) {
            long time = getElapsedTime();
            sidePanel.this.clock.setText(String.valueOf(time));        
        }
    });
    timer.setRepeats(true);
    add(pane);

}

@Override
public void actionPerformed(ActionEvent e) {
    if(e.getSource() == toggle)
    {
        if(timer.isRunning())
        {
            endTime = System.currentTimeMillis();
            timer.stop();
        }
        else
        {
            startTime = System.currentTimeMillis();
            timer.start();
        }
    }
}

You can then strip out the functionality from you StopWatch (ie the getElapsedTime())

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! didnt even know there was a javax.swing.Timer
For some reason, it's still not working, i put the edited code in the post

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.