# Das schöne Bouncing Ball Beispiel.



## Jayman (30. Jun 2007)

Hi Jungs,
ich habe im Netz das schöne Bouncing Ball Beispiel gefunden, wo ein Ball immer von Ecke zu Ecke hüpft...
So, ich habe jedoch ein sehr, sehr ausführliches Beispiel gefunden, wo erst einmal auf einen Start-Button gedrückt werden muss, damit alles los geht...
Ich habe das versucht zu entfernen, jedoch ist dann leider kein Ball mehr zu sehen...
Kann mir jemand helfen, dass zu start des Programms sofort der Ball hüpft. Auch die Buttons Start und Ende wären zu viel...
Der Code:


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

///////////////////////////////////////////////////////////////////
// main() creating a frame object and displaying it on the screen.
public class Bounce {

  public static void main(String args[]) {
    JFrame frame = new BounceFrame();
    frame.show();
  }
}

class BounceFrame extends JFrame {
  private JPanel canvas;
  private static final int XSIZE = 10;
  private static final int YSIZE = 10;
  private int x = 0;
  private int y = 0;
  private int dx = 2;
  private int dy = 2;

  // Constructor is just creating the pane filling it with information.
  public BounceFrame() {
    setSize(300, 200);
    setTitle("Bounce");

    addWindowListener(new WindowAdapter() {
      public void windowCLosing(WindowEvent e) {
        System.exit(0);
      }
    });

    Container contentPane = getContentPane();
    canvas = new JPanel();
    contentPane.add(canvas, "Center");

    JPanel p = new JPanel();
    addButton(p, "Start", new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        Ball b = new Ball(canvas);  // Creating the ball and bouncing it.
        b.bounce();
      }
    });

    addButton(p, "Close", new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        System.exit(0);
      }
    });

    contentPane.add(p, "South");
  }

  /////////////////////////////////////////////////////////////////
  // Declaring the actions caused by adding a button.
  public void addButton(Container c, String title, ActionListener a) {
    JButton b = new JButton(title);
    c.add(b);
    b.addActionListener(a);
  }

  /////////////////////////////////////////////////////////////////
  // Class to move the ball across the screen.
  class Ball {
    private JPanel box;

    public Ball(JPanel b) {
      box = b;
    }

    // Drawing the ball.
    public void draw() {
      Graphics g = box.getGraphics();
      g.fillOval(x, y, XSIZE, YSIZE);
      g.dispose();
    }

    // Method actually moving the ball across screen.
    public void move() {
      Graphics g = box.getGraphics();
      g.setXORMode(box.getBackground());
      g.fillOval(x, y, XSIZE, YSIZE);
      x += dx;
      y += dy;
      Dimension d = box.getSize();
      if (x<0) {
        x = 0;
        dx = -dx;
      }

      if (x + XSIZE >= d.width) {
        x = d.width - XSIZE;
        dx = -dx;
      }

      if (y < 0) {
        y = 0;
        dy = -dy;
      }

      if (y + YSIZE >= d.height) {
        y = d.height - YSIZE;
        dy = -dy;
      }

      g.fillOval(x, y, XSIZE, YSIZE);
      g.dispose();
    }

    // Move the ball, then sleep for 25 ms, and move again, etc.
    public void bounce() {
      draw();
      for (int i=1; i<500; i++) {
        move();
        try {
          Thread.sleep(25);
        }
        catch (InterruptedException e) {
          System.err.println();
        }
      }
    }
  }
}
```


----------



## madboy (30. Jun 2007)

```
JPanel p = new JPanel(); 
    addButton(p, "Start", new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
        Ball b = new Ball(canvas);  // Creating the ball and bouncing it. 
        b.bounce(); 
      } 
    }); 

    addButton(p, "Close", new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
        System.exit(0); 
      } 
    }); 

    contentPane.add(p, "South");
```
mach alles bis auf das hier weg:

```
Ball b = new Ball(canvas);  // Creating the ball and bouncing it. 
b.bounce();
```

Da steht eigentlich sogar dran, was den Ball erzeugt ???:L


----------



## Marco13 (1. Jul 2007)

Von "schön" ist das weit weg. Ich sag nur: getGraphics  :autsch: 
Ich finde, diese kack-funktion sollten sie ein für alle mal aus der API verbannen  :x


----------



## Jayman (1. Jul 2007)

Danke, aber das habe ich ja auch schon versucht, dann kommt eine Exception:
"Exception in thread "main" java.lang.NullPointerException
	at BounceFrame$Ball.draw(Bounce.java:77)
	at BounceFrame$Ball.bounce(Bounce.java:115)
	at BounceFrame.<init>(Bounce.java:44)
	at Bounce.main(Bounce.java:11)"


----------



## Marco13 (1. Jul 2007)

Na sowas  :shock: getGraphics scheint 'null' zurückzuliefern? Woran DAS wohl liegen mag? :roll:

http://java.sun.com/products/jfc/tsc/articles/painting/
http://www.java-forum.org/de/viewtopic.php?t=46550&highlight=awt+swing+tutorial

Und ein Beispiel, mit mehreren hüpfenden Bällen, die aber "richtig" hüpfen. Wenn sie (Wie schwerelos) im Raum rumfliegen sollen, muss eine Zeile geändert werden
http://www.java-forum.org/de/viewtopic.php?p=304602#304602


----------



## Jayman (1. Jul 2007)

Jep,
Deine zweite URL aus diesem Forum habe ich auch schon gefunden, jedoch läuft dieses nicht bei mir ( nur so zur Info). Es öffnet sich zwar ein Fenster, jedoch ist dieses ein Balken & auch die Funktionen darin hmm...
Ok, also es liegt an getGraphics in dem Bouncing Programm.
Das hilft schon mal. danke.


----------



## Marco13 (1. Jul 2007)

Hm - "die zweite URL aus diesem Forum" - heißt das, dass das "Balls"-Beispiel nicht geht? Wie seiht ein Fenster aus, das "ein Balken ist"? Das erstellen des Fensters müßte eigentlich auch vom Event-Dispatch-Thread gemacht werden, aber es würde mich wundern, wenn das hier Probleme machen würde  ???:L  Naja. Vielleicht kannst du dein Beispiel ja noch so umbauen, dass es kein getGraphics mehr verwendet.


----------



## Jayman (1. Jul 2007)

Also, beim Starten deines Programms erhalten wir so ein Fenster:






Wenn ich dieses vergrößere, dann sieht es so aus:


----------



## Marco13 (1. Jul 2007)

Versuchst du das als Applet zu starten oder sowas? Wo kommt denn das Menü her? Das "Click here to start" stammt jedenfalls auch nicht von mir :wink: Notfalls mal an der Konsole
javac BallTest.java
java BallTest
versuchen. Oder doch dein Beispiel umbauen.


----------



## Jayman (1. Jul 2007)

Ich werde es versuchen umzubauen.
Aber theoretisch benötige ich doch auch nicht die Zeilen 59-63 (mit dem Button), oder?!


----------



## Marco13 (1. Jul 2007)

Wenns gleich loslaufen soll, brauchst du den Button nicht. Ja.


----------



## Jayman (1. Jul 2007)

Also, wenn ich die Sachen entferne erhalte ich ja das:

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

///////////////////////////////////////////////////////////////////
// main() creating a frame object and displaying it on the screen.
public class Bounce{

  public static void main(String args[]) {
	    JFrame frame = new BounceFrame(); 
	    frame.show(); 
  }
}

class BounceFrame extends JFrame {
  private JPanel canvas;
  private static final int XSIZE = 10;
  private static final int YSIZE = 10;
  private int x = 0;
  private int y = 0;
  private int dx = 2;
  private int dy = 2;

  // Constructor is just creating the pane filling it with information.
  public BounceFrame() {
    setSize(300, 200);
    setTitle("Bounce");

    addWindowListener(new WindowAdapter() {
      public void windowCLosing(WindowEvent e) {
        System.exit(0);
      }
    });

    Container contentPane = getContentPane();
    canvas = new JPanel();
    contentPane.add(canvas, "Center");
   	  
        Ball b = new Ball(canvas);  // Creating the ball and bouncing it.
        b.bounce();

  }

  /////////////////////////////////////////////////////////////////
  // Class to move the ball across the screen.
  class Ball {
    private JPanel box;

    public Ball(JPanel b) {
      box = b;
    }

    // Drawing the ball.
    public void draw() {
      Graphics g = box.getGraphics();
      g.fillOval(x, y, XSIZE, YSIZE);
      g.dispose();
    }

    // Method actually moving the ball across screen.
    public void move() {
      Graphics g = box.getGraphics();
      g.setXORMode(box.getBackground());
      g.fillOval(x, y, XSIZE, YSIZE);
      x += dx;
      y += dy;
      Dimension d = box.getSize();
      if (x<0) {
        x = 0;
        dx = -dx;
      }

      if (x + XSIZE >= d.width) {
        x = d.width - XSIZE;
        dx = -dx;
      }

      if (y < 0) {
        y = 0;
        dy = -dy;
      }

      if (y + YSIZE >= d.height) {
        y = d.height - YSIZE;
        dy = -dy;
      }

      g.fillOval(x, y, XSIZE, YSIZE);
      g.dispose();
    }

    // Move the ball, then sleep for 25 ms, and move again, etc.
    public void bounce() {
      draw();
      for (int i=1; i<500; i++) {
        move();
        try {
          Thread.sleep(25);
        }
        catch (InterruptedException e) {
          System.err.println();
        }
      }
    }
  }
}
```

So, also es liegt an dem Zeichen des Balls. Ich habe versucht, jedoch kommt mir nicht in den Kopf weshalb das nicht geht. Ich habe schon einen Stickman programmiert & dort auch immer mit graphics gearbeitet,aber hier passt es nicht...Warum?!


----------



## Quaxli (2. Jul 2007)

Hier ist eine lauffähige Version. Ich habe einiges umgestellt und auch die veraltete JFrame.show() rausgeworfen. Ganz zufrieden bin ich noch nicht mit dieser Version, aber ich hätte das Ganze von Anfang an anders hochgezogen. Allerdings dachte ich mir, daß die ursprüngliche Version erkennbar sein sollte.

Die ursprüngliche Version war, wie schon Marco13 angemerkt hat, nicht wirklich gut. Meine dürfte etwas besser sein 


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

public class Bounce {

	public static void main(String args[]) {
		BounceFrame bf = new BounceFrame();
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setTitle("Bounce");
		frame.setSize(400, 400);
		frame.setLocation(100, 100);
		frame.getContentPane().add(bf);
		frame.setVisible(true);
		bf.start();
	}
}

class BounceFrame extends JPanel {

	private static final long	serialVersionUID	= 1L;

	Ball											ball;
	boolean										gameon						= true;

	public BounceFrame() {
		ball = new Ball(this);
	}

	public void paint(Graphics g) {
		super.paint(g);
		ball.draw(g);
	}
	
	public void start(){
		bounce();
	}

	public void bounce() {

		while (gameon) {

			ball.move();
			repaint();

			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				System.out.println(e);
			}

		}

	}

	class Ball extends Rectangle {

		private static final long	serialVersionUID	= 1L;
		private JPanel						box;
		private int								dx								= 2;
		private int								dy								= 2;

		public Ball(JPanel b) {
			box = b;
			width = 10;
			height = 10;
		}

		// Drawing the ball.
		public void draw(Graphics g) {
			g.fillOval(x, y, width, height);
		}

		// Method actually moving the ball across screen.
		public void move() {

			x += dx;
			y += dy;
			
			if (x < 0) {
				x = 0;
				dx = -dx;
			}

			if (x + width >= box.getWidth()) {
				x = box.getWidth() - width;
				dx = -dx;
			}

			if (y < 0) {
				y = 0;
				dy = -dy;
			}

			if (y + height >= box.getHeight()) {
				y = box.getHeight() - height;
				dy = -dy;
			}

		}

	}

}
```


----------



## Jayman (2. Jul 2007)

Dickes Danke,
ich werde es später versuchen laufen zu lassen.


----------



## Quaxli (2. Jul 2007)

Jayman hat gesagt.:
			
		

> ...ich werde es später *versuchen* laufen zu lassen.



Ich habe schon für weniger getötet.  :wink:  :wink:  :wink: 
Das Ding läuft auf jeden Fall.


----------



## merlin2 (2. Jul 2007)

Jayman fragt sich, ob *er* es schafft das Programm zum Laufen zu bekommen.
Wenn er es *versuchen* wird, hat er wohl öfter Probleme mit dem Starten einer Java-Anwendung.


----------



## Marco13 (2. Jul 2007)

:toll: Das kann ich bestätigen  :toll: 


			
				Jayman hat gesagt.:
			
		

> Also, beim Starten deines Programms erhalten wir so ein Fenster:
> :autsch:
> Wenn ich dieses vergrößere, dann sieht es so aus:
> :autsch: :autsch:


:wink:


----------



## Quaxli (3. Jul 2007)

@Merlin2:

Wenn ich sowas reinschreibe:  :wink:  :wink:  :wink: 
Dann ist es nur Spaß  :bae: - dafür sind die Dinger da.  :wink:


----------



## merlin2 (3. Jul 2007)

Tut mir leid, aber ich habe das " :wink:  :wink:  :wink: " auf die Zeile bezogen, in der es stand. :bae:


----------



## Jayman (3. Jul 2007)

Jep, alles ok.
Bin jetzt alles Stück für Stück durchgegangen & habe eine Frage zu der Variablen 'private static final long serialVersionUID = 1L;'.
Wenn diese nicht verwendet wird meckert Eclipse. Lauefn tut es auch ohne, aber was macht diese Variable & weshalb ist diese auf 1L gesetzt?


----------



## merlin2 (3. Jul 2007)

Die brauchst du, wenn du Objekte deiner Klasse serialisieren willst. Du kannst sie auch weglassen und, damit Eclipse nicht "meckert", Folgendes vor deine Klasse schreiben:
	
	
	
	





```
@SuppressWarnings("serial")
```


----------

