Applet Paralleles Thread Handling

JavaPaint

Mitglied
Hallo zusammen,

ich lasse gerade mit Hilfe von Threads ein paar Bälle in einem Fenster hin und her springen.
Die Bälle haben verschiedene Farben. Sobald ich den 4. Ball erstelle, gibt es eine bunte Schmiererei.
Wie kann ich das vermeiden?
Danke

Java:
package Billiard;

import java.awt.*;

import javax.swing.*;

public class Tisch extends JApplet {

	public void init(){
		Graphics g = getGraphics();
		setSize(300,400);
		getContentPane().setBackground(Color.white);
		
		Ball b1 = new Ball(40,40,3,1,50,10,g,this,Color.green);
		Ball b2 = new Ball(100,100,1,-5,100,40,g,this,Color.yellow);
		Ball b3 = new Ball(0,40,7,2,150,100,g,this,Color.red);
		Ball b4 = new Ball(0,200,1,1,30,20,g,this,Color.black);
	}
	
}

Java:
package Billiard;

import java.awt.*;

import javax.swing.*;

public class Ball extends Thread implements Runnable{

	public int x,xalt;	// X-Position
	public int y,yalt;	// y-Position
	public int dx;		// x-Alt-Position
	public int dy;		// y-Alt-Position
	public int r;		// Radius
	public int speed;	// Geschwindigkeit
	public JApplet a;	// Applet
	public Color c;		// Ballfarbe
	public Graphics g;	// Grafik 
	
	public int breite;		// Applet-Fenster-Breite
	public int hoehe;		// y-Position
	
	public Ball(int X, int Y, int DX, int DY, int U, int SPEED, Graphics g,JApplet applet, Color C){
		x = X;
		y = Y;
		dx = DX;
		dy = DY;
		r = U/2;
		speed = SPEED;
		c = C;
		this.g = g;	
		a = applet;
		start();		// Starte Thread
	}
	
	public void run(){

		while (Thread.currentThread() == this){ 
			try
			{   this.sleep(speed);
				bewegen();
			}
			catch (InterruptedException e) { }
		}
	}
	
	// Ball zeichnen
	public void zeichnen(){	
		g.setColor(c);
		g.fillArc(x,y,r,r,0,360);
	}
	
	// Alte Position "löschen"
	public void loeschen()
	{
	 Color f= a.getBackground();
	 g.setColor(f);
	 g.fillArc(xalt,yalt,r,r,0,360);
	}
	
	// Den Ball bewegen
	public void bewegen(){
		// Positionen verändern
		xalt = x;
		yalt = y;
		x += dx;
		y += dy;
		
		  // aktuelle Fenstergröße ermitteln
		 Rectangle rec=a.getBounds();
		 breite=rec.width;
		 hoehe=rec.height;
		 		
		// Stoßt links an
		if (x < 0){
			dx = -dx;
		}
		
		// Stoßt oben an
		if (y < 0){
			dy = -dy;
		}	
		
		if (x > (breite-(r))){ dx = -dx;}
		if (y > (hoehe-(r))){ dy = -dy;}
		
		loeschen();
		zeichnen();
	}
	


}
 
Niemals getGraphics() aufrufen, wenn man nicht ganz genau weiß, was man macht.
In deinem Fall ist das ohnehin unnötig.
Zum Zeichnen ist die paintComponent()-Methode eines JPanels zu überschreiben, welches du dann ins Applet einbettest.
Das JApplet ist ein Toplevel-Container (genau wie JFrame, JDialog), in den niemals direkt gezeichnet wird.
 
Hallo,

danke für deine Antwort! Ich habe eine private Panel Klasse programmiert und male nun
auf einem Panel. Allerdings ist das Problem nicht behoben. Wahrscheinlich liegt das immer noch an
getGraphics();
Ich komme allerdings nicht darauf, wie ich paint(Graphics g) >objektorientiert< in der Ball Klasse implementiere, so dass ich später nur: new Ball(...); aufrufen kann.

Kann mir da jemand vielleicht auf die Sprünge helfen?

Java:
import java.awt.*;

import javax.swing.*;


public class Tisch extends JApplet {

	
	public void init(){
		Graphics g = getGraphics();
		setSize(300,400);
		JPanel p = new MalPanel();
		JButton btn = new JButton("btn");
		
		p.setBackground(Color.blue);
		p.setSize(300,400);
		this.getContentPane().setLayout(new BorderLayout());
		this.getContentPane().add(p,"Center");

		
		Ball b1 = new Ball(40,40,3,1,50,10,g,this,p,Color.green);
		Ball b2 = new Ball(100,100,1,-5,100,40,g,this,p,Color.yellow);
		Ball b3 = new Ball(0,40,7,2,150,100,g,this,p,Color.red);
		Ball b4 = new Ball(0,200,1,1,30,20,g,this,p,Color.white);
		Ball b5 = new Ball(20,80,-7,2,15,80,g,this,p,Color.black);
		Ball b6 = new Ball(180,40,1,1,30,20,g,this,p,Color.orange);
		
	}


    
	private class MalPanel extends JPanel{
		   public MalPanel(){}
		   public void paint(Graphics g){
	           super.paint(g);

	           Graphics2D g2d = (Graphics2D) g;
		   }
	}
	
}
 
Ich weis nicht, was du mit dem [JAPI]Graphics[/JAPI]-Object in irgendeinem Konstruktor willst. Ein Graphics-Objekt ist nie etwas festes oder greifbares, es stellt nur Methoden zur Verfügung, um auf eine Zeichenfläche (Canvas - nicht zu verwechseln mit der gleichnamigen AWT-Klasse) zu malen.
Ein [JAPI]BufferedImage[/JAPI] z.B. kann auch eine solche Zeichenfläche sein, sogar eine, die man auf eine andere Zeichenfläche malen (okay, stempeln) kann. Zwei dieser vielen int-Werte im Ball-Konstruktor sind mit Sicherheit doch Breite und Höhe des Balls (für exakt runde Bälle genügt sogar einer von beiden), dann könnte die Ball-Klasse wie folgt aussehen (davon ausgehend, dass der erste Wert der Durchmesser ist):
Java:
class Ball extends BufferedImage {
  Ball(int a, int b, int c, int d, int e, int f, Color c) {
    super(a, a, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2d = createGraphics();
    // hier wird der Ball wie gewohnt gezeichnet
    g2d.setColor(c);
    g2d.fillOval(0, 0, a, a);
  }
}
anschliessend können die Bälle in der Paint des MalPanels wie folgt gezeichnet werden:
Java:
public void paintComponent(Graphics g) {
  super.paintComponent(g);
  g.drawImage(ball, x, y, null);
}
Ich nehme mal stark an, dass die ganzen ints im Konstruktor die Bounds des MalPanels oder die Ballpositionen sind. Wenn dem so ist... die gehören da nicht hin. 😉
 
Zuletzt bearbeitet von einem Moderator:

Zurück
Oben