Hi! I am new to java and I'm trying to make a Stop Clock which shows time in minutes, seconds and mili-seconds. I've attached the zip file with this thread which includes the source code and other files required to run the program. The problem which I'm facing is that as soon as I click on the start button of my stop clock the applet gets stuck and nothing happens.
Please tell me where I'm going and the way to correct it. It would be even more obliging if you give me the corrected code itself. Thanks in advance.

Recommended Answers

All 12 Replies

Can't be bothered to mess around with your zip - please post code in proper format here.
But at a guess you're blocking the Swing thread...

Everything to do with Swing (eg painting the screen, running actionPerformed methods) happens on a single thread - the "Event Dispatch Thread", or "EDT", or "Swing thread".
That means that once your actionPerformed method starts NOTHING else will happen in Swing, including no screen updates, until your method finishes. You can update stuff and loop and sleep as much as you like, but none of that will affect what's on the screen until your method has terminated.
If you want to do stuff in steps over a period of time the this is the right way:
In your actionPerformed start a javax.swing.Timer, and return. Every time the timer fires you can update whatever needs updating and return. Inbetween the timer firings Swing will be free to update the screen.

I've used an image as the background of my stop clock and have added different components over it that's why I attached the zip file....Alright here's the code..

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import sun.audio.*;
class Stop_Clock
{static boolean flag=true;
public static void main(String argsp[])
{
JFrame frame=new JFrame("Stop Clock");
frame.setResizable(false);
JLabel lbl=new JLabel(new ImageIcon("Stop CLock.png"));
frame.setIconImage(new ImageIcon("078474-blue-jelly-icon-business-clock8.png").getImage());
lbl.setLayout(null);
final JLabel mins=new JLabel(" 00");
mins.setFont(new Font("Impact", Font.BOLD, 45));
mins.setBounds(125, 80, 75, 44);
final JLabel secs=new JLabel(" 00");
secs.setFont(new Font("Impact", Font.BOLD, 45));
secs.setBounds(244,80, 75, 44);
final JLabel msecs=new JLabel(" 000");
msecs.setFont(new Font("Impact", Font.BOLD, 45));
msecs.setBounds(355, 80, 95, 44);
lbl.add(msecs);
lbl.add(secs);
lbl.add(mins);
final JLabel start=new JLabel();
start.setBounds(11,173,181,57);
lbl.add(start);
start.addMouseListener(new MouseAdapter(){
public void mouseEntered(MouseEvent e){
start.setIcon(new ImageIcon("start-changed.png"));
}
public void mouseExited(MouseEvent e){
start.setIcon(new ImageIcon("start.png"));}
public void mouseClicked(MouseEvent e){
flag=true;
int sec=1, msec=1, min=1;
while(flag==true)
{sec=1;
while(sec<=60&&flag==true)
{msec=1;
while(msec<=1000&&flag==true){
try{Thread.sleep(1);} catch(InterruptedException error){}
String str=String.format(" %03d",msec);
if(msec==1000) msecs.setText(" 000");
else msecs.setText(str);
msec++;
}
String str1=String.format(" %02d",sec);
if(sec==60) secs.setText(" 00");
else secs.setText(str1);
sec++;
}
String str2=String.format(" %02d", min);
mins.setText(str2);
min++;
}
}
});
final JLabel stop=new JLabel();
stop.setBounds(349, 173, 181,57);
lbl.add(stop);
stop.addMouseListener(new MouseAdapter(){
public void mouseEntered(MouseEvent e){
stop.setIcon(new ImageIcon("stop-changed.png"));
}
public  void mouseExited(MouseEvent e){
stop.setIcon(new ImageIcon("stop.png"));
}
public void mouseClicked(MouseEvent e){
flag=false;
msecs.setText(" 000");
secs.setText(" 00");
mins.setText(" 00");
}
});
final JLabel reset=new JLabel();
reset.setBounds(216,178,113,47);
lbl.add(reset);
reset.addMouseListener(new MouseAdapter(){
public void mouseEntered(MouseEvent e){
reset.setIcon(new ImageIcon("reset-changed.png"));
}
public void mouseExited(MouseEvent e){
reset.setIcon(new ImageIcon("reset.png"));
}
public void mouseClicked(MouseEvent e){
flag=false;

}
});
frame.add(lbl, "Center");
frame.pack();
frame.show();
}
}

Indentation would allow us to read that, but anbyway, line 42 onwards - it's exactly what I explained in my previous post

So how to fix it? Please if you can correct it and post the right thing...It's urgent..!! Please..!!

As a matter of kindness to you (and anyone else reading this), I'll post the existing code properly indented; however, no one here is going to fix the problem for you. We will give advice, but not free homework answers. In any case, the answer was already given to you above - use javax.swing.Timer, which will run without blocking the overall thread. See this tutorial for more details on how to use it.

As for the urgency of the problem... well, keep in mind that it isn't urgent to us, and that we are here mostly to help you learn, not to help you finish your homework. See this essay for further Illumination fnord.

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import sun.audio.*;
class Stop_Clock {
    static boolean flag=true;
    public static void main(String argsp[]) {
        JFrame frame=new JFrame("Stop Clock");
        frame.setResizable(false);
        JLabel lbl=new JLabel(new ImageIcon("Stop CLock.png"));
        frame.setIconImage(new ImageIcon("078474-blue-jelly-icon-business-clock8.png").getImage());
        lbl.setLayout(null);
        final JLabel mins=new JLabel(" 00");
        mins.setFont(new Font("Impact", Font.BOLD, 45));
        mins.setBounds(125, 80, 75, 44);
        final JLabel secs=new JLabel(" 00");
        secs.setFont(new Font("Impact", Font.BOLD, 45));
        secs.setBounds(244,80, 75, 44);
        final JLabel msecs=new JLabel(" 000");
        msecs.setFont(new Font("Impact", Font.BOLD, 45));
        msecs.setBounds(355, 80, 95, 44);
        lbl.add(msecs);
        lbl.add(secs);
        lbl.add(mins);
        final JLabel start=new JLabel();
        start.setBounds(11,173,181,57);
        lbl.add(start);
        start.addMouseListener(new MouseAdapter() {
            public void mouseEntered(MouseEvent e) {
                start.setIcon(new ImageIcon("start-changed.png"));
            }
            public void mouseExited(MouseEvent e) {
                start.setIcon(new ImageIcon("start.png"));
            }
            public void mouseClicked(MouseEvent e) {
                flag=true;
                int sec=1, msec=1, min=1;
                while(flag==true) {
                    sec=1;
                    while(sec<=60&&flag==true) {
                        msec=1;
                        while(msec<=1000&&flag==true) {
                            try {
                                Thread.sleep(1);
                            }
                            catch(InterruptedException error) {}
                            String str=String.format(" %03d",msec);
                            if(msec==1000) msecs.setText(" 000");
                            else msecs.setText(str);
                            msec++;
                        }
                        String str1=String.format(" %02d",sec);
                        if(sec==60) secs.setText(" 00");
                        else secs.setText(str1);
                        sec++;
                    }
                    String str2=String.format(" %02d", min);
                    mins.setText(str2);
                    min++;
                }
            }
        });
        final JLabel stop=new JLabel();
        stop.setBounds(349, 173, 181,57);
        lbl.add(stop);
        stop.addMouseListener(new MouseAdapter() {
            public void mouseEntered(MouseEvent e) {
                stop.setIcon(new ImageIcon("stop-changed.png"));
            }
            public  void mouseExited(MouseEvent e) {
                stop.setIcon(new ImageIcon("stop.png"));
            }
            public void mouseClicked(MouseEvent e) {
                flag=false;
                msecs.setText(" 000");
                secs.setText(" 00");
                mins.setText(" 00");
            }
        });
        final JLabel reset=new JLabel();
        reset.setBounds(216,178,113,47);
        lbl.add(reset);
        reset.addMouseListener(new MouseAdapter() {
            public void mouseEntered(MouseEvent e) {
                reset.setIcon(new ImageIcon("reset-changed.png"));
            }
            public void mouseExited(MouseEvent e) {
                reset.setIcon(new ImageIcon("reset.png"));
            }
            public void mouseClicked(MouseEvent e) {
                flag=false;

            }
        });
        frame.add(lbl, "Center");
        frame.pack();
        frame.show();
    }
}

Alright!! @Schol-R-LEA or anybody seeing this post ...can you tell me what exactly I have to do besides telling the error in the code which JamesCherrill has already told..

The first thing to do is get rid of the existing code in the start.mouseClicked() event handler. Those loops aren't working; you need something that will run each time the Timer event fires. From here on in, all that start.mouseClicked() will do is start the Timer, and all stop.mouseClicked() will do is stop it. The code for resetting the values of msec, sec, and min, and the text of msecs, secs, and mins, will now go in the reset.mouseClicked() event handler.

Next, you need to move the msec, sec, and min integers out to the class level as static variables, while at the same time eliminating the variable flag (you won't need it any more). This allows you to have them changed by the various event listeners.

Next, you will need to declare a Timer, and define an ActionListener for it with a suitable actionPerformed() method. This I'll leave to you, but I want to remind you: don't loop inside the event handler. It will automagically get re-run every tim the Timer event fires. Write your code with that in mind.

As a last piece of advice, replace frame.show(); with frame.setVisible(true);, as show() is deprecated. Just a minor thing to fix.

There are 2 thing that may help fix your problem. At least anyone of them is enough for the task.
1.Thread
2.javax swing Timer.

1.if you need thread then you will need to call the runnable method to innitiate the clock. This must be called in an event.

  1. If you use the javax swing timer, then thhats more easier..
    Timer timer = new Timer(int);
    then you innitiate the timer.start(); in the event.

Also to make things more protective . Always organize data that you will use in many places so that there wont be a subtle error.

here.

Font font = new Font("Impact", Font.BOLD, 45);

min.setFont(font);

You get the idea?

I forgot something earlier: you need to add some code at the end of the program to ensure that the program exits correctly when the window is closed. This code I'll just give to you:

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                timer.stop();
            }
        });

Otherwise, the Java VM may hang on you.

@Schol-R-LEA...there's one thing more I want to ask...if I put the updation of sec, msec and min in the reset.mouseClicked() event handler, there will be no updation until and unless the reset button is clicked so how will it work??

Sorry, looking at it now I see that I wasn't clear. The code for updating the values (incrementing them on each millisecond, second and minute, as appropriate) should be in the timer.actionPerformed() handler; only the code to reset all the values back to zero should be in reset.MouseClicked(). I hope that makes more sense now.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.