?
Solved

Threads don't work with JFrame

Posted on 2000-04-08
12
Medium Priority
?
310 Views
Last Modified: 2006-11-17
My program use JFrame and thread.  But the out put stop after a little while.

import java.awt.event.*;
import javax.swing.*;
import java.applet.*;
import java.awt.*;
import  java.net.URL;
import  java.util.*;


public class Tryit extends JFrame implements Runnable{

  Thread  thread = null;

  Train train1, train2;
   
  Position p1 = new Position( 100,200 ), p2 = new Position(110,80);

  Container c;
 
  public Tryit() {
   
     c = getContentPane();
     train1 = new Train( 1, p1 );
     train2 = new Train( 2, p2 );
     train1.start();
     train2.start();
     System.err.println( " after construct of try it ! ");
  }
   

  public void run(){
     
    System.err.println( " try it run begin! ");
   
    while (true) {
       
      repaint();

            try {
                Thread.sleep(10);
            } catch (InterruptedException e){
            // the VM doesn't want us to sleep anymore,
            // so get back to work
            }
     }

  }

   
  public static void main(String[] args) {

        Tryit frame = new Tryit();

        WindowListener l = new WindowAdapter() {
            public void windowClosing(WindowEvent e) {System.exit(0);}
        };

        frame.addWindowListener(l);
        frame.setSize(1200, 980);

        frame.show();
        System.err.println( " after show! ");
    }


  public void paint( Graphics g ){
   
    System.err.println( " tryit paint! ");
    train1.paint( g );
    train2.paint( g );

  }
}


/**
  Train.java
*/


class Train extends Thread {

  private  int  trainNo,  dx = 2, dy = 2 ;
  private  int  x, y;
  private  Position  currentPosition;
   
  public Train( int no, Position p ) {
    trainNo = no;
    currentPosition = p;
  }

  public void run(){
     
    while ( true ){

         
            try {
                Thread.sleep(1);
            } catch (InterruptedException e){
            // the VM doesn't want us to sleep anymore,
            // so get back to work
            }
             
       x = currentPosition.getX();
       y = currentPosition.getY();
 
       x = x + dx ;
       y = y + dy;
       if ( x < 0 ) dx/=-2;
       if ( x > 900 ) dx*=-2;
       if ( y < 0 ) dy/=-2;
       if ( y > 500 ) dy*=-2;
       
       currentPosition.setX( x );
       currentPosition.setY( y );


       System.err.println( " train while "+trainNo+" end once! ");
       
   }
  }

  public void paint( Graphics g ){

     g.drawOval( currentPosition.getX() -2, currentPosition.getY() - 2, 5, 5);
     System.err.println( " train paint "+trainNo+" end! ");
  }
}


/**
  Position.java
*/


class Position {

  private  int  x,y;

  public Position( int x1,  int y1 ) {
    x = x1;
    y = y1;
  }

  public  int  getX( ) {
    return  x;
  }

  public  int  getY( ) {
    return  y;
  }

  public  void  setX( int x1 ) {
    x = x1;
  }

  public  void  setY( int y1 ) {
    y = y1;
  }
}
 
0
Comment
Question by:flameonice
  • 6
  • 6
12 Comments
 
LVL 7

Expert Comment

by:Sasha_Mapa
ID: 2697466
A.
>> while (true){
>>    repaint();
>>    try{
>>      Thread.sleep();
>>    } catch (InterruptedException e) {}
>> }

This is just plain simple HORRIBLE. You should NEVER do such a thing. Whenever one of your objects updates, only then you should repaint it.
It's a good thing your forgot to run a new thread that would execute that code!!

B. The "Position" class is already implemented in java, it's named java.awt.Point.

C. Well, of course -- You shouldn't see any updates on the screen at all because you are changing the positions of your trains but never bother to repaint and your horrible code that I described in (A) is never executed (I assume it was intended to repaint) because you never run a new Thread with your class (which is Runnable) as the parameter for the constructor.
0
 

Author Comment

by:flameonice
ID: 2698373
Please tell me how to change my program.  I am not quite clear with that.  Thanks.
0
 
LVL 7

Expert Comment

by:Sasha_Mapa
ID: 2698428
Well, something like this should work:


import java.awt.event.*;
import javax.swing.*;
import java.applet.*;
import java.awt.*;
import  java.net.URL;
import  java.util.*;


public class Tryit extends JFrame implements Runnable{

   private Thread  thread = null;
   private Train train1, train2;
   private boolean stop; //  set this to true when you want to stop the trains
   Container c;
   Position p1 = new Position( 100,200 ), p2 = new Position(110,80);                    
   public Tryit() {
       train1 = new Train( 1, new Point(100,200) );
       train2 = new Train( 2, new Point(110,180) );
   }
                         
   public void run(){
      while (!stop){
         train1.move();
         train2.move();
         repaint();
         try {
            Thread.sleep(10);
         } catch (InterruptedException e){return;}
      }
   }

   public static void main(String[] args) {
      Tryit frame = new Tryit();

      WindowListener l = new WindowAdapter() {
          public void windowClosing(WindowEvent e) {System.exit(0);}
       };

       frame.addWindowListener(l);
       frame.setSize(1200, 980);
       frame.show();
       thread = new Thread(frame);
       thread.start(); // This executes the run() method in another thread.
   }


   public void stopMovingTrains(){
      stop = true;
   }

   public void paint( Graphics g ){
       train1.paint(g);
       train2.paint(g);
   }
}


/**
   Train.java
*/

class Train {

   private  int  trainNo,  dx = 2, dy = 2 ;
   private  Point  currentPosition;
                         
   public Train( int no, Point p ) {
       trainNo = no;
       currentPosition = p;
   }

   public void move(){
       int x = currentPosition.getX(); // x and y should be local variables.
       int y = currentPosition.getY();
                       
       x = x + dx ;
       y = y + dy;
       if ( x < 0 ) dx/=-2;
       if ( x > 900 ) dx*=-2;
       if ( y < 0 ) dy/=-2;
       if ( y > 500 ) dy*=-2;
       currentPosition.move(x,y);
   }

   public void paint( Graphics g ){
      g.drawOval( currentPosition.x -2, currentPosition.y - 2, 5, 5);
   }
}


There might still be some small bugs in this code here and there :-)
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 

Author Comment

by:flameonice
ID: 2698455
Please tell me how to change my program.  I am not quite clear with that.  Thanks.
0
 
LVL 7

Expert Comment

by:Sasha_Mapa
ID: 2698518
Just did that, didn't I?
0
 

Author Comment

by:flameonice
ID: 2698612
Yes.  It work now.  Is that possible for me to erase previous painted oval before repaint?  Thanks.
0
 

Author Comment

by:flameonice
ID: 2698843
Yes.  It work now.  Is that possible for me to erase previous painted oval before repaint?  Thanks.
0
 
LVL 7

Expert Comment

by:Sasha_Mapa
ID: 2699091
It is not needed, it should get erased by itself, because repaint() asks the system to call update(Graphics) which clears the component with the background color and then calls paint(Graphics) so if you don't override update(Graphics), it should erase whatever you painted last time.

I'm going away until Friday so I won't be able to answer any questions until then, sorry.
0
 
LVL 7

Expert Comment

by:Sasha_Mapa
ID: 2699093
Generally, if you want to erase something, you would use g.setColor(getBackground()) and g.fillRect(x,y,width,height) to fill a rectangle with the background color.
0
 

Author Comment

by:flameonice
ID: 2709455
I debugged the program you gave me.  It works, but can not erase previous painted oval.  I append it below.


import java.awt.event.*;
import javax.swing.*;
import java.applet.*;
import java.awt.*;
import  java.net.URL;
import  java.util.*;


public class Tryit2 extends JFrame implements Runnable{

   private Thread  thread = null;
   private Train train1, train2;
   private boolean stop; //  set this to true when you want to stop the trains
   Container c;
   Position p1 = new Position( 100,200 ), p2 = new Position(110,80);                    
   public Tryit2() {
       train1 = new Train( 1, new Position(100,200) );
       train2 = new Train( 2, new Position(110,180) );
   }
                         
   public void run(){
      while (!stop){
         train1.move();
         train2.move();
         repaint();
         try {
            Thread.sleep(100);
         } catch (InterruptedException e){return;}

         System.err.println( " tryit run end! ");
      }
   }

   public static void main(String[] args) {
      Tryit2 frame = new Tryit2();

      WindowListener l = new WindowAdapter() {
          public void windowClosing(WindowEvent e) {System.exit(0);}
       };

       frame.addWindowListener(l);
       frame.setSize(1200, 980);
       frame.show();
       frame.thread = new Thread(frame);
       frame.thread.start(); // This executes the run() method in anotherthread.
   }


   public void stopMovingTrains(){
      stop = true;
   }

   public void paint( Graphics g ){
       train1.paint(g);
       train2.paint(g);
       System.err.println( " tryit paint end! ");
   }
}


/**
   Train.java
*/

class Train {

   private  int  trainNo,  dx = 1, dy = 1;
   private  Position  currentPosition;
                         
   public Train( int no, Position p ) {
       trainNo = no;
       currentPosition = p;
   }

   public void move(){
       int x = currentPosition.getX(); // x and y should be local variables.
       int y = currentPosition.getY();
                       
       x = x + dx ;
       y = y + dy;
       if ( x < 0 ) dx/=-1;
       if ( x > 900 ) dx*=-1;
       if ( y < 0 ) dy/=-1;
       if ( y > 500 ) dy*=-1;
       
       currentPosition.setX( x );
       currentPosition.setY( y );
       System.err.println( " train "+trainNo+" x "+x+" y "+y);

   }

   public void paint( Graphics g ){
     g.drawOval( currentPosition.getX() -2, currentPosition.getY() - 2, 5, 5);
     System.err.println( " train paint "+trainNo+" end! ");
   }
}


/**
  Position.java
*/


class Position {

  private  int  x,y;

  public Position( int x1,  int y1 ) {
    x = x1;
    y = y1;
  }

  public  int  getX( ) {
    return  x;
  }

  public  int  getY( ) {
    return  y;
  }

  public  void  setX( int x1 ) {
    x = x1;
  }

  public  void  setY( int y1 ) {
    y = y1;
  }
}
0
 
LVL 7

Accepted Solution

by:
Sasha_Mapa earned 200 total points
ID: 2716145
Sorry for answering so late, I was away.
I'm not sure why JFrame's update method doesn't paint the background, but this should solve the problem:
Add the following lines to the beginning of the paint(Graphics) method in class Tryit2:

g.setColor(getBackground());
Rectangle r = getBounds();
g.fillRect(0,0,r.width,r.height);

I hope this code is self explanatory :-)
0
 

Author Comment

by:flameonice
ID: 2718573
Thank you.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Java Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collectio…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…

569 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question