this code shows the second oval only when maximize is pressed otherwise only the one oval is shown and the first oval does not go to the getHeight() where as the one appearing after maximizing repaints correctly

import javax.swing.*;
import java.awt.Graphics;
class drawpanel extends JComponent
 implements Runnable
{
    int i=10,startx;
	Thread t;
	  drawpanel(int y)
	   {
	    	startx=y;
            t=new Thread(this);
	        t.start();
       }

     public	void paintComponent(Graphics g)
	{
          super.paintComponent(g);
	      g.drawOval(startx,i,10,10);
    }


	public void run()
    {
	  int checker=0;
	  while(true)
	       {
	       	  try{
		         	if(i<getHeight()&&checker==0)
		        	     {
		        	     	i++;
			              repaint();
			             }
			       else if(i==getHeight())
			          {
			          	checker=1;
				       }
				        if(checker==1)
				        {
				         	i--;
				        	repaint();

				      	}

		            	if(i==0)
				        checker=0;
		                 Thread.sleep(1);
			     }
			catch(Exception ex)
			{

			}

			}

     }

}







public class balls {

    public static void main(String[] args) {

    JFrame frame=new JFrame();
    frame.setSize(800,600);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.show();

  try{

  	 frame.add( new drawpanel(10) );
     Thread.sleep(1000);
  	 frame.add(new drawpanel(300));
  	

  	}
  	catch(Exception ex)
  	{}






    	    }
}



	}

After one minute you add the second component which is the new ball with the x coordinate of 300. Then you should immediately ask the JFrame to re-arrange the layout via the following code:
frame.validate();
Therefore, you should insert the line of code into line 84 (shortly after the
catch(Exception ex){}
that is:

public static void main(String[] args) {

    JFrame frame=new JFrame();
    frame.setSize(800,600);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

  try{
  	 frame.add( new drawpanel(10) );
  	 Thread.sleep(3000);
  	 frame.add(new drawpanel(300));
  		}catch(Exception ex){}
  	frame.validate();
    };

It is written in Java API 1.6 as follows.
"The validate method is used to cause a container to lay out its subcomponents again. It should be invoked when this container's subcomponents are modified (added to or removed from the container, or layout-related information changed) after the container has been displayed."

Edited 6 Years Ago by tong1: The quotation comes from Java API 1.6

After one minute you add the second component which is the new ball with the x coordinate of 300. Then you should immediately ask the JFrame to re-arrange the layout via the following code:
frame.validate();
Therefore, you should insert the line of code into line 84 (shortly after the
catch(Exception ex){}
that is:

public static void main(String[] args) {

    JFrame frame=new JFrame();
    frame.setSize(800,600);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

  try{
  	 frame.add( new drawpanel(10) );
  	 Thread.sleep(3000);
  	 frame.add(new drawpanel(300));
  		}catch(Exception ex){}
  	frame.validate();
    };

It is written in Java API 1.6 as follows.
"The validate method is used to cause a container to lay out its subcomponents again. It should be invoked when this container's subcomponents are modified (added to or removed from the container, or layout-related information changed) after the container has been displayed."

yeah thanks it displays the second ball but after resizing the window the first ball does not get to to edge of Frame.whereas the second ball repaints properly.

the first ball does not get to to edge of Frame

What variables control where the first ball is shown?
Have you tried debugging the code by adding println()s to show how the variables are changing and how the execution flow is going?

The border control variable for the balls’ movement is obtained from the method getHeight() of the JComponent. It returns the current height of this component. I have debugged the code by adding println()s to show how the variables are changing and how the execution flow is going. I have also observed the movements of both balls.
It is found that when resizing the frame the first component still moves within its initial region while the region where the second ball moves has changed accordingly, resulted in such a scenario where the size of the first component (the first ball) remains unchanged while the size (height) of the second component (the second ball) changes accordingly. I have also made the drawing class as an inner class to see if there is any difference. The scenario remains the same. Does the phenomenon show an deficiency in resizing a frame in Java ?

Edited 6 Years Ago by tong1: n/a

I think there are conflicts with parts of Swing or layout managers with your code.
Try this version:

/*
this code shows the second oval only when maximize is pressed otherwise only the one oval is shown 
and the first oval does not go to the getHeight() where as the one appearing after maximizing repaints correctly 

*/

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


public class DrawPanelProblem extends JComponent   implements Runnable  {
    int i=10,
        startx;
	Thread t;
   String name;

	  DrawPanelProblem(int x, String nm)	   {
         super.setSize(100, 100); // ???
         name = nm;
	    	startx=x;
          t=new Thread(this);
	       t.start();
     }

     public	void paintComponent(Graphics g)	{
          super.paintComponent(g);
	       g.drawOval(startx,i,10,10);
    }
    //------------------------------------------------------------------
    // Override some component methods to see what is happening
    public void setBounds(int x, int y, int width, int height) {
      super.setBounds(x, y, width, height);
      System.out.println(name + " set Bounds x=" + x + ", y=" + y + ",  height=" + height + ", w=" + width);
    }
    public void setBounds(Rectangle r) {
      super.setBounds(r);
      System.out.println(name + " set Bounds r.x=" + r.x + ", r.height=" + r.height);
    }

    Dimension ourDim = new Dimension(400, 400);
    public Dimension getPreferredSize() {
      System.out.println("getPS+ " + super.getPreferredSize());
      return ourDim;
    }


   //--------------------------------------------------------
	public void run()     {
	  int checker=0;
	  while(true) 	       {
//         System.out.println(name + "  gH=" + getHeight());

      	if(i<getHeight()&&checker==0) 		        	     {
     	     	   i++;
	       } else if(i==getHeight())			          {
	          	checker=1;
		    }
		    if(checker==1)				        {
		         	i--;
	       }
          if(i==0)
	            checker=0;

	       repaint();

          try{        Thread.sleep(1);      }catch(Exception ex) 			{	     }
		} // end while()
   } // end run()

   //---------------------------------------------
   public static void main(String[] args) {

       JFrame frame=new JFrame();
       frame.setSize(800,600);
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//       frame.setVisible(true);
       Container contr = frame.getContentPane();
     	 contr.add( new DrawPanelProblem(10, "@10"), BorderLayout.WEST);
//     	 contr.validate();
//       try{ Thread.sleep(1000);}catch(Exception x){}
     	 contr.add(new DrawPanelProblem(300, "@300"), BorderLayout.EAST);
//     	 contr.validate();
       frame.setVisible(true);
       Component[] comps = contr.getComponents();
       System.out.println("#comps=" + comps.length);
   }
}

Thank you, NormR1. I have tested your code. Yes, it works when the BorderLayout is used swhere two balls are moving in different "subframes":BorderLayout.EAST and BorderLayout.WEST. I have tried FlowLayout, resulted int an overlap of two components. In a game program, two objects (balls) should be moving within one frame rather than two: EAST and WEST. Therefore, we have to figure out the right Layout Manager. Meanwhile programming in J2ME shows different balls are able to move within a common frame. Are they associated with one thread or different threads? We have to make further investigation.

Edited 6 Years Ago by tong1: n/a

I think there are conflicts with parts of Swing or layout managers with your code.
Try this version:

/*
this code shows the second oval only when maximize is pressed otherwise only the one oval is shown 
and the first oval does not go to the getHeight() where as the one appearing after maximizing repaints correctly 

*/

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


public class DrawPanelProblem extends JComponent   implements Runnable  {
    int i=10,
        startx;
	Thread t;
   String name;

	  DrawPanelProblem(int x, String nm)	   {
         super.setSize(100, 100); // ???
         name = nm;
	    	startx=x;
          t=new Thread(this);
	       t.start();
     }

     public	void paintComponent(Graphics g)	{
          super.paintComponent(g);
	       g.drawOval(startx,i,10,10);
    }
    //------------------------------------------------------------------
    // Override some component methods to see what is happening
    public void setBounds(int x, int y, int width, int height) {
      super.setBounds(x, y, width, height);
      System.out.println(name + " set Bounds x=" + x + ", y=" + y + ",  height=" + height + ", w=" + width);
    }
    public void setBounds(Rectangle r) {
      super.setBounds(r);
      System.out.println(name + " set Bounds r.x=" + r.x + ", r.height=" + r.height);
    }

    Dimension ourDim = new Dimension(400, 400);
    public Dimension getPreferredSize() {
      System.out.println("getPS+ " + super.getPreferredSize());
      return ourDim;
    }


   //--------------------------------------------------------
	public void run()     {
	  int checker=0;
	  while(true) 	       {
//         System.out.println(name + "  gH=" + getHeight());

      	if(i<getHeight()&&checker==0) 		        	     {
     	     	   i++;
	       } else if(i==getHeight())			          {
	          	checker=1;
		    }
		    if(checker==1)				        {
		         	i--;
	       }
          if(i==0)
	            checker=0;

	       repaint();

          try{        Thread.sleep(1);      }catch(Exception ex) 			{	     }
		} // end while()
   } // end run()

   //---------------------------------------------
   public static void main(String[] args) {

       JFrame frame=new JFrame();
       frame.setSize(800,600);
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//       frame.setVisible(true);
       Container contr = frame.getContentPane();
     	 contr.add( new DrawPanelProblem(10, "@10"), BorderLayout.WEST);
//     	 contr.validate();
//       try{ Thread.sleep(1000);}catch(Exception x){}
     	 contr.add(new DrawPanelProblem(300, "@300"), BorderLayout.EAST);
//     	 contr.validate();
       frame.setVisible(true);
       Component[] comps = contr.getComponents();
       System.out.println("#comps=" + comps.length);
   }
}

Ok i understood i little bit you did there.
Correct me if wrong but this code moves the balls within their container space that is EAST or WEST i made the ball move towards the x axis and it did not work.Actually what i want to do is to make a program to move a no. balls all over the frame and then setting the BorderLayout wont work.

Edited 6 Years Ago by gauravk_bhanot: n/a

You may try to use one Thread only in your program.
Your class drawpanel will have attributes x,y only. That is, you define each ball as an instance with their own attributes x and y.

Edited 6 Years Ago by tong1: n/a

It works with one Thread. You may add a button (not JButton) so that when client clicks, one more ball will be added. One should be noticed that the JButton, which is lightweight component, will not be shown on the heavyweight stuff( e.g. awt Graphics). That's why only Button(the heavyweight component) works. You may also setLayout(null), so that the button may use setBounds(int, int, int, int) method to have its own location and size. Then you may start a coding for a game..... Good luck.

/*
Only one Thread is used. You may have more balls up to 10.
*/

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


public class Balls extends JFrame implements Runnable {
	
	static Ball balls[]= new Ball[10];
    static int count=0;
    Thread timer = null;
    
    class Ball {  // inner class 
    	int x,y;  // each ball has its own location indicated by x,y
    	boolean flag;  // each ball has its own flag to direct if y++ or y--
    	
    	public Ball(int x){
    		flag=true;
    		y=0;
    		this.x=x;
    	}
    	
    	public void drawball(Graphics g){ // draw itself
    		g.setColor(Color.red);
    		g.fillOval(x,y,10,10);
    		if (flag)
    		y++;
    		else
    		y--;
    		if (y >= getHeight())  // inner class may call any method of its outer class
    		flag = false;
    		else
    		if (y <=0)
    		flag = true;
    	}
    } // end of the inner class
    
    public void start(){
    	if (timer == null){
    		timer = new Thread(this);
    		timer.start();
    	}
    }
    public void run(){
    	while(timer !=null){
    		try{
    			Thread.sleep(10);
    		}catch(InterruptedException e){}
    		repaint();
    	}
    }
    
    public void paint(Graphics g){
    	g.setColor(Color.white);
    	g.fillRect(0,0,800,600);
    	for (int i=0; i<count; i++){ // draw each ball
    	balls[i].drawball(g);
    	System.out.println("count: " + count);
    	}
    	}
    public Balls(){
       setSize(800,600);
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       setVisible(true);
       balls[count++]= new Ball(10);
       start(); // start the thread. the first ball appears
       try{ Thread.sleep(5000);}catch(InterruptedException x){}
       balls[count++]= new Ball(200); // 5 minutes later the second ball appears
    }
    
   public static void main(String[] args) {
       Balls b = new Balls();
   }
}

Edited 6 Years Ago by tong1: n/a

This question has already been answered. Start a new discussion instead.