Solved

Threads don't work with JFrame

Posted on 2000-04-08
12
276 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
Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

 

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 50 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

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.

786 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