Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 334
  • Last Modified:

Sleep?

Hi,

Please see this excerpt of code....

if ((onLight) && (greenLight == false)){
            greenLight = true;
            System.out.println("Green");
            repaint();
           
            try{
                System.out.println("Asleep");
                Thread.currentThread().sleep(5000);
            }
            catch(InterruptedException e){
            }
        }

What I want to know is why does it sleep before the repaint() method is called, even though the sleep method is after it in the code??

Thanks
0
cullenswood
Asked:
cullenswood
1 Solution
 
TimYatesCommented:
This is a Swing application yeah?

Swing performs all of it's painting in  another thread, so it cannot start doing the painting, as you have the processor control...

try:

if ((onLight) && (greenLight == false)){
           greenLight = true;
           System.out.println("Green");
           repaint();
           Thread.yield() ;
           
           try{
               System.out.println("Asleep");
               Thread.currentThread().sleep(5000);
           }
           catch(InterruptedException e){
           }
       }
0
 
girionisCommented:
 It is always a good practice to have the repaint() after the sleep so the component can immediately repaint after the thread "wakes up".
0
 
cullenswoodAuthor Commented:
That Thread.yield() didn't actually make any difference to it.   I understand that it would probably be better to have the repaint after the sleep (probably was going to have that aswell), its just that I want the program to do a repaint before it goes to sleep.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
cullenswoodAuthor Commented:
Oh, and yes it is a Swing Application
0
 
AlephCommented:
A call to repaint() does not necessarily result in a call to paint() immediately, it only tells the component that it should be repainted sometime soon. (Because of this several calls to repaint() can result in one call to paint().)

If the repaint() call in your code is made from inside some event driven part of you code, you will have the event handler thread, which I believe is involved in repainting aswell, sleeping. If that is the case repainting will be done after you have returned from the event triggered method, and thus after you have sleept for five seconds.
0
 
cullenswoodAuthor Commented:
Fair enough, thanks Aleph.   You dont know anyway around that by any chance??!
0
 
AlephCommented:
I guess that depends on what you intend to do with your program. One possibility might be to have another thread call repaint(), but it is usually better to solve problems without introducing more threads since they can slow things done and have a tendency to cause rather complicated bugs. Perhaps you could tell me a little bit more about what all this should actually do?
0
 
cullenswoodAuthor Commented:
Basically Aleph,

THe program has a line, with dots along it.   When greenLight is true, the number of dots is going to decrease, when it is red the number will increase.  

if ((onLight) && (greenLight == false)){
           greenLight = true;
           System.out.println("Green");
           repaint();
           
           try{
               System.out.println("Asleep");
               Thread.currentThread().sleep(5000);
           }
           catch(InterruptedException e){
           }
           number -= 5;
           repaint();
       }

What I wanted it to do was that the greenLight would change, it would sleep for 5 secs, then the dots would decrease by 5.   But what is happening is that the greenLight is changing, and the dots decreasing, at the same time, after it has slept.

0
 
AlephCommented:
Ok. In that case you could try to use another thread as a timer. Basically what you could do is to create a small class that runs as a thread (extends Thread) and, when it is started, just waits for a while and then does whatevery you like. There is actually a Timer class in the Java API which does something like that (and a couple of other things, for that matter).

It's documentation is available on the web at: http://java.sun.com/j2se/1.4/docs/api/java/util/Timer.html
0
 
cullenswoodAuthor Commented:
Thanks for the help Aleph.   Can I ask u one more little question.   Below basically is the code for the small program I have made so far.   As it is, when u click on the red dot/light it changes to green, and vice versa.   What I eventually want to be able to do is have a program that every so often changes the light from green to red (ie a certain probability (say 1/p) that it will change to red) for a set number of seconds.   When it is red, there will be a probability (1/n) that extra dots will be added to the line, and when it is green a certain amount of dots (m) will be taken off the line!!!  
Hope I explained it ok!!

What I want to know is, would I do this by using threads or how??   I know it will probably be one continuous loop, going from green to red to green etc, but how would I go about doing the bit inbetween.

Thanks for your previous help anyway, greatly appreciated.




import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class TLight extends JFrame implements MouseListener,
                                                MouseMotionListener{

    static double length;
    static int points[][];
    private JLabel statusBar;
    int maxCars, number;
    static boolean greenLight;
    private boolean onLight, doubleClick;

    public TLight(){
        super("Traffic Light");

        statusBar = new JLabel();
        getContentPane().add(statusBar, BorderLayout.SOUTH);
        addMouseListener(this);
        addMouseMotionListener(this);

        maxCars = 13;
        number = 13;

        length = Math.sqrt(Math.pow((200 - 200), 2) + Math.pow((300 - 100), 2));

    }

    public void paint( Graphics g ) {
        g.clearRect( 0, 0, 400, 400);
        draw(g);
    }

    public void draw(Graphics g){

        points = new int [maxCars][2];
        int count = 0;
        points[0][0] = 300;
        points[0][1] = 200;
        for(int i = 1; i < number; i++){
            points[i][0] = (int)(300 - (length / maxCars) - count);
            points[i][1] = 200;
            count += length/maxCars;
        }
        if (number < 13){
            for (int i = number; i < 13; i++){
                points[i][0] = points[number-1][0];
                points[i][1] = points[number-1][1];
            }
        }

        g.drawLine( 100, 200, 300, 200);

        if (greenLight == false){
            g.setColor(Color.RED);
        }
        else{
            g.setColor(Color.GREEN);
        }
        g.fillOval( 300, 180, 20, 20);

        for (int i = 0; i < points.length; i++){
            int r = (int)(Math.random() * 256);
            int gg = (int)(Math.random() * 256);
            int b = (int)(Math.random() * 256);
            g.setColor(new Color( r, gg, b));
            g.fillOval( points[i][0] - 10, (points [i][1] - 10), 10, 10);

        g.setColor(Color.BLACK);
        }
    }
    public void onTLight( int mouseX, int mouseY ) {
        doubleClick = false;
        int x = 300 + 10;
        int y = 200 - 10;
        int xdiff = mouseX-x;
        int ydiff = mouseY-y;
        onLight = (xdiff*xdiff + ydiff*ydiff <= 100 /* 10*10(ie radius) */ );


        if ((onLight) && (greenLight == false)){
            greenLight = true;
            System.out.println("Green");
            repaint();

            number -= 4;

        }
        else if ((onLight) && (greenLight == true)){
            greenLight = false;
            System.out.println("Red");
            repaint();

            number += 3;

        }
    }

    public void mouseClicked(MouseEvent e){
       
    }

    public void mousePressed(MouseEvent e){
        onTLight(e.getX(), e.getY());

    }

    public void mouseReleased(MouseEvent e){
   
    }

    public void mouseEntered(MouseEvent e){
       
    }

    public void mouseExited(MouseEvent e){
       
    }

    public void mouseDragged(MouseEvent e){

    }

    public void mouseMoved(MouseEvent e){
       
    }

    public static void main( String args[] ) {
        TLight app = new TLight();
        app.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        app.setSize( 400, 400 );
        app.setVisible( true );
    }
}
0
 
AlephCommented:
If you use the Timer class, one way to do it could be to simply add TimerTasks that the timer should repeat with a short period. Each time a TimeTask object you have created is executed, you could with a small probability change the light, or add or remove some dots.

Another way is to randomize a delay to the next time the light should change, and instruct the Timer to execute a TimerTask that changes the light after that delay.

As I understand, it is possible to add multiple TimerTasks to a Timer object, so you could create just one Timer object and use it for all timed things.
0
 
cullenswoodAuthor Commented:
Cheers Aleph,

Thanks for the help and ideas.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now