Jump to content

Java - Countdown using Thread problem

- - - - -

  • Please log in to reply
15 replies to this topic

#1
Serialcek

Serialcek

    Learning Programmer

  • Members
  • PipPipPip
  • 72 posts
Hi guys :)

I have a problem with a method using countdown.


public void countdown(){

    		  for(int i = 5; i >= 0; i-- ){

    				  if(i == 0) System.exit(0);

    				  try{

    					 Thread.sleep(1000);

    					}

    				  catch(InterruptedException e){}				  

    				  System.out.print("Time: "+i);

    				  

    				  }

    		  }


So the problem is, that I have to extend Thread in the class.. Like this:

public class Something extends javax.swing.JFrame,Thread {


But I'm getting an error... In the other classes where I used a countdown with thread there was no problem.. why I can't extend Thread here?

#2
Serialcek

Serialcek

    Learning Programmer

  • Members
  • PipPipPip
  • 72 posts
I guess nobody know my precedent problem :/

But I have one more newbie problem..



public class resitev {


	public void resitev(int x, int y) {

		int resitev = x + y;

	}


	public void sprintaj() {

		int x = 3;

		int y = 4;

		resitev(x, y);

		System.out.print(resitev); // I don't get it why I get here an error

	}


	public static void main(String[] args) {

	}

}


Can someone help me please :)
I'm still a begginer here

#3
lethalwire

lethalwire

    while(false){ ... }

  • Members
  • PipPipPipPipPipPipPip
  • 748 posts
  • Programming Language:Java, PHP
  • Learning:Java, PHP
You cannot extend multiple classes. You can however, implement multiple interfaces.
I'd suggest extending JFrame and implementing the Runnable interface.

Defining and Starting a Thread (The Java™ Tutorials > Essential Classes > Concurrency)

Your second problem is that you defined resitev out of the scope of sprintaj.
Example:


method1() { //method1's scope starts here

    int a = 1;

    int b = 2;

} //method1's scope starts here

method2() { //start of method2's scope

    int c = a + b; // error, a b were declared inside of method1's scope. So you can't use them!

} // end of method2's scope


In your case, you declared resitev outside of the scope of your context.

#4
Serialcek

Serialcek

    Learning Programmer

  • Members
  • PipPipPip
  • 72 posts
Thx...but I have still a problem..it doesn't work like it should..


public void run() {

		int c=5;

		while(c>0) {

		

			try {

				Thread.sleep(1000);

			} catch (InterruptedException x) {

			}


			System.out.print("Time:" +c);  //This is working corectly

	        Time_left.setText("Time: "+c); // This is not working.

	        c--;

			

		}

		

	}


So what i have:

Time_left is a Jlabel and I want it that it shows how many time I have.
But it doesn't work...
But System.out.println does want I want...

#5
ZekeDragon

ZekeDragon

    Writes binary right handed and hex left handed

  • Moderators
  • 2,103 posts
Don't use setText directly (unless this Runnable is used exclusively by a Swing Timer, Event Call, or anything else executed by the Event Dispatch Thread), normally just tell Swing's Event Dispatch Thread to make modifications to the GUI. Swing is not thread safe.

Anyway, did you tell Time_left to repaint after performing the setText operation?
	        Time_left.setText("Time: "+c); // This is not working.

	        Time_left.repaint();

Wow I changed my sig!

#6
Serialcek

Serialcek

    Learning Programmer

  • Members
  • PipPipPip
  • 72 posts
Hi i just tried like you said but it's not working too :/

#7
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
How exactly do you start this thread / run method?

Edited by wim DC, 16 February 2011 - 09:30 AM.


#8
Serialcek

Serialcek

    Learning Programmer

  • Members
  • PipPipPip
  • 72 posts
I start thread like:

(new Thread(Class_Name())).start();


also works if i call just

run();


But I think that the problem is not here because as I sad the part when I simply print

System.out.print("Time:" +c);

works good :)

#9
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
Yea, i asked it because if you did it by just calling run() , it might have not worked.
If for example you would start it by pressing a button on the frame, then run(); wouldn't have been good. Because the window won't be updated as long as you're in the actionPeformed method of the button.
new Thread(....) ...start() would have solved this.

Propably a silly question but... you did add the Time_left label to the frame right? :p
(I mean, maybe you just don't see the text change cause the label isn't on it. It doesn't cause any errors or compile problems if you make a new Label but don't add it..)

This example works just fine:


import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;


public class CountdownFrame extends JFrame {


    private JLabel label;


    public CountdownFrame() {

        label = new JLabel();

        add(label);

        JButton button = new JButton("start");

        button.addActionListener(new ActionListener() {


            public void actionPerformed(ActionEvent e) {

                (new Thread(new CountDown())).start();

            }

        });

        add(button, BorderLayout.SOUTH);

        

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setSize(300,300);

        setVisible(true);

    }


    class CountDown implements Runnable {


        public void run() {

            int c = 5;

            while (c > 0) {

                try {

                    Thread.sleep(1000);

                } catch (InterruptedException x) {

                }

                label.setText("Time: " + c--);

            }


        }

    }


    public static void main(String[] args){

        CountdownFrame frame = new CountdownFrame();

    }

}



#10
Serialcek

Serialcek

    Learning Programmer

  • Members
  • PipPipPip
  • 72 posts
Yesss now works perfectly...Thx man..
And yes of course I had a label on the frame and yes it was visible :P

As I see the only differece between mine and yours code is:

  label.setText("Time: " + c--);


 Time_left.setText("Time: "+c)


thx again man :)

#11
lethalwire

lethalwire

    while(false){ ... }

  • Members
  • PipPipPipPipPipPipPip
  • 748 posts
  • Programming Language:Java, PHP
  • Learning:Java, PHP
Perhaps your variable 'c' had to be volatile. It would have to be declared outside of of run() though.

I stole Wim DC's code( sorry :P )
This seems to work fine.

package thread;


import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;


public class CountdownFrame extends JFrame {


    private JLabel label;


    public CountdownFrame() {

        label = new JLabel();

        add(label);

        JButton button = new JButton("start");

        button.addActionListener(new ActionListener() {


            public void actionPerformed(ActionEvent e) {

                (new Thread(new CountDown())).start();

            }

        });

        add(button, BorderLayout.SOUTH);

        

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setSize(300,300);

        setVisible(true);

    }


    class CountDown implements Runnable {

    	volatile int c; [COLOR="red"]// changed here[/COLOR]

        public void run() {

        	c = 5;[COLOR="red"] // and here[/COLOR]

            while (c > 0) {

            	--c; [COLOR="red"]// and here[/COLOR]

                try {

                    Thread.sleep(1000);

                } catch (InterruptedException x) {

                }

                label.setText("Time: " + c);

            }


        }

    }


    public static void main(String[] args){

        CountdownFrame frame = new CountdownFrame();

    }

}



#12
Serialcek

Serialcek

    Learning Programmer

  • Members
  • PipPipPip
  • 72 posts
I read now something about what means volatile but didn't understand it well... anyway I think that there is no need to use volatile..it works good for now :P
Amm but now I have one new problem.. my CPU is getting 100% usage becouse of threads..

So what I have:
I'm doing actually a quiz for two players.. When they starts -> the countdown starts and if the countdown ends they lose but if they answer correctly they get another question and countdown has to be restarted. I read that Threads cannot be restarted. They have to be kiilled. But as I try to do that it doesn't work :/

So when the game is started the 2 countdown Thread are started too:

(new Thread(new LCountDown())).start();

(new Thread(new RCountDown())).start();


But when some player answer correctly to one question I should killed the precedent Thread and start the new one...

if (answer == correct){    // Pseudo-code

(new Thread(new RCountDown())).destroy();  // And  I just don't know what to do now... 

(new Thread(new RCountDown())).start();

}


And I need a solution for these problem becouse in my method Countdown I added a possibilty to chech if time is up

if (c <= 0) {

Time_left.setText("Lose!");

}


But if I don't kill this Thread when someone answer corectly the time will expire anyway becouse the Thread is still running and new countdown will not start because the variable c of the precedent Thread will be still 0.

Anyone understad my problem? :)
Thanks in advance




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users