Gleicher Inhalt bei unterschiedlichen JPanels

bspainkf36

Erfahrenes Mitglied
Hey,
ist etwas schwierig mein Problem in der Betreffzeile zu schildern :(

Ich habe eine Klasse View(erbt von JPanel) von der ich die Klassen A, B und C ableite. Ich habe mir in der Klasse A eine BufferdeImage-Objekt erzeugt und male in diesem herum.

Jetzt zu meinem Problem. Wenn ich in dem BufferedImage Objekt zeichne, wird das Bild auch auf die Klassen B und C übertragen, obwohl sie in keiner direkten Assoziation mit dem BufferedImage Objekt von A stehen. Ich zeichne zwar auch in B und C, dies geschieht indirekt über A (BufferedImage wird in einem Array abgelegt und anschließend in B und C dargestellt).

Das Problem tritt nur direkt beim Mahlen auf. Wenn ich beispielsweise Eclipse in den Vordergrund hole, so dass mein Fenster nicht mehr zu sehen ist, und anschließend den JFrame wieder in den sichtbaren Bereich ziehe, wird alles richtig dargestellt. Anscheinend ruft das Betriebssystem separat jede einzelne paint-Methode der JPanels auf und alles wird richtig angezeigt.

Code:
private static final long serialVersionUID = 1027176525973253122L;

Ich habe auch die serialVersionsUID in der View sowie A,B und C Klasse implementiert, doch leider wird beim Zeichnen weiterhin in jedem der drei Panels das gleich Bild dargestellt während des Zeichnens angezeigt.

Danke für eure Hilfe :)

Greetz Kon
 

Anhänge

  • 24429attachment.png
    24429attachment.png
    2 KB · Aufrufe: 15
Hallo!

Also aus deiner Erklärung könnte man mal vermuten, dass du den beiden View Sub-Klassen B und C die gleiche Referenz auf das BufferedImage von A unterschiebst. Zeichnest du dann in B und C auch dieses BufferedImage, dann siehst du natürlich das was du in A gezeichnet hast, da ja B und C auch auf dieses BufferedImage verweisen.

Gruß Tom
 
Hey,
das habe ich schon probiert definitiv auszuschließen. Aber naja ... :( Von dem Aufbau ist es so, dass A in das BufferedImage schreibt und anschließend die Daten in einem zweidimensionalen boolean Array speichert.

Die Klassen B und C greifen dann mit ihren paint-Methoden auf diesen Array zu und zeichnen die neuen Koordinaten in ihr jeweiliges Graphics-Objekt - in den Klassen B und C überschreibe ich die Methode Paint.

Bei jeder Bewegung der Maus rufe ich die repaint() - Methode aller Panels (A,B,C) auf und dabei tritt dann der Fehler auf. Wenn ich die repaint vom Betriebssystem aufrufen lasse, das Fenster durch ein anderes Programm überlappen und anschließend wieder in den Vordergrund ziehen, funktioniert die Geschichte wunderbar. Das Problem tritt nur auf, wenn ich die repaint selber aufrufe ...

Ich bin zur Zeit nicht zu Hause, aber ich werde heute Abend mal den Code reinstellen. Mit diesem blöden Problem schlage ich mich schon seit zwei Tagen rum :( Danke für die Hilfe :)

Greetz Kon
 
Hey,
hier mein Code. Ich starte mit einer Klasse, die sich sich eine Instanz von A, B und C erzeugt und anschließend an Control übergibt.

Code:
class View extends JPanel {
	private static final long serialVersionUID = 8774341878975246575L;
}

Code:
class A extends View {
	private static final long serialVersionUID = 1027176525973253122L;
	private int _xPosNew;
	private int _yPosNew;
	private int _xPosOld;
	private int _yPosOld;
	private BufferedImage _bufferedImage;

	public A(){
		_bufferedImage = new BufferedImage( 300, 300, BufferedImage.TYPE_INT_ARGB);
	}

	public void setPosNew(int posxNew, int posyNew) {
		_xPosNew = posxNew;
		_yPosNew = posyNew;

		Graphics g = _bufferedImage.getGraphics();
		g.setColor(new Color(255,0,0));
		g.drawLine(_xPosOld,_yPosOld,_xPosNew,_yPosNew);
		_xPosOld = _xPosNew;
		_yPosOld = _yPosNew;
		g.dispose();
		this.repaint();
	}

	public void setPosOld(int posxOld, int posyOld) {
		_xPosOld = posxOld;
		_yPosOld = posyOld;
	}

	public void paint(Graphics g) {
		g.drawImage(_bufferedImage, 0, 0, this);
	}

	public BufferedImage getBufferedImage() {
		return _bufferedImage;
	}
}

Code:
class B extends View {
	private static final long serialVersionUID = -7810510332169203043L;

	public void paint(Graphics g) {
		//zeichne mit den neuen Daten aus dem Array
	}
}

Die Klasse C hat den gleichen Inhalt wie B, liest nur andere Daten aus.

Code:
class Control extends MouseAdapter implements MouseMotionListener {
	private static Control _control;
	private A _a;
	private B _b;
	private C _c;
	//Zaehler für die Aufrufe der MouseDragged
	private int _counter;

	private Control() {
		_counter = 0;
	}

	public static synchronized Control getInstance() {
		if (_control == null) {
			_control = new Control();
		}
		return _control;
	}

	public void setABC(A a, C c, B b){
		_a = a;
		_c = c;
		_b = b;
		_a.addMouseMotionListener(this);
		_a.addMouseListener(this);
	}

	public void updateData() {
		//array für b und c wird geupdated ...
	}

	public void mouseDragged(MouseEvent e) {
		_a.setPosNew(e.getX(),e.getY());
		if (_counter == 9) {
			updateData();
			_counter = 0;
		}

		_counter++;
		//aktualisiere die Darstellung bei a und b
		_c.repaint();
		_b.repaint();
	}

	public void mouseReleased(MouseEvent e) {
		updateData();
		//aktualisiere die Darstellung bei Bob und Eves
		_c.repaint();
		_b.repaint();
	}

	public void mousePressed(MouseEvent e) {
		_a.setPosOld(e.getX(), e.getY());
	}

	public void mouseMoved(MouseEvent e) {
	}
}

Ich habe die Klasse A beim Listener angemeldet und den Inhalt der Paint-Methoden der beiden Klassen B und C auskommentiert. Trotzdem wird immer das gleiche Bild angezeigt, wie in A. Danke für die Hilfe :)

Greetz Kon
 
Zuletzt bearbeitet:
Hallo Kon,

füge in die leeren paintMethoden von B und C noch folgende Zeile hinzu:

super.paint(g);

Dann wird der Zauber verschwinden!


Vg Erdal
 
Hallo,
danke für die Antworten. Es funktioniert jetzt, ich frage mich nur warum :) Beim Minimieren habe ich wohl versehentlich den Konstruktor in den Klassen Eve und Bob nicht mit kopiert. Jedoch enthalten die Konstruktoren den super() Aufruf. Jetzt frage ich mich, warum ich den Aufruf explizit angeben muss. Danke

Greetz Kon
 
Zurück