Graphics Objekt - aus anderer Klasse aufrufen / übergeben

lal000r

Mitglied
Hallo zusammen,

Ich ecke momentan mit der Swing-paintComponent-Methode immer wieder an.
Zunächst habe ich eine Klasse, die von JPanel abgeleitet ist und die paintComponent-Methode überschreibt.
Innerhalb dieser paintComponent-Methode wird das Graphics-Objekt an diverse Methoden übergeben, damit diese ebenfalls zeichnen können. (Alles innerhalb dieser Klasse)

Nun habe ich allerdings eine weitere Klasse (Animator), die von Thread abgeleitet ist und das genannte Panel übergeben bekommt. Innerhalb dieser Klasse sollen Spielfiguren gezeichnet werden, die über das Panel "wandern" sollen. Dazu lasse ich die Zeichenvorgänge innerhalb des Animationsthreads immer mal wieder für einige Millisekunden schlafen, damit eine Animation entsteht.
Das Problem ist jetzt nur folgendes:

Zunächst erzeuge ich in der Panel-Klasse innerhalb der paintComponent einen neuen Animator-Thread, der dann die Animationsmethoden in der run()-Methode ausführt. Das funktioniert auch soweit.
ABER.. die Methode in der run() braucht zum Zeichnen das Graphics-Object.
Nur wie komme ich an dieses Objekt außerhalb der Panelklasse? Zum Testen habe ich im Konstruktor des Animators das Panel mit übergeben und ziehe mir das Graphics-Objekt mit panel.getGraphics().

Funktionieren tut dies, allerdings ist mir bekannt, dass man das nicht so machen sollte. Außerdem führt es zum Flackern bei der Animation.
Wie komme ich also von außerhalb an das Graphics-Objekt, bzw. wie initiiere ich eine Methode von außerhalb die das Graphics-Objekt benötigt?

Wenn es gewünscht ist, kann ich auch gern etwas Code posten. Vielen Dank schonmal! :)
 
Zuletzt bearbeitet:
S

SlaterB

Gast
grundsätzlich (später das große Aber)
paintComponent startet keinen Thread, das können andere machen,

der Thread muss sich für Graphics nicht interessieren, seine Berechnungen können unabhängig vom Zeichnen sein,
er bestimmt den aktuellen Zeitpunkt, berechnet meinetwegen Positionen usw., und dann folgt nur ein Befehl: repaint()
-> schon ist auf sauberen Wege irgendwann die paint-Methode dran, die nimmt sich was an Informationen nötig ist und malt exakt den aktuellen Zustand

dabei ist evtl. an Synchronisation oder andere Absprache zu denken, damit nicht doch der Thread gleichzeitig weiterarbeitet und bisschen was während des Zeichnens verändert

-----

das große Aber: Flackern bei Hochleistungs-Zeichnen ist mit diesem Verfahren glaube ich nicht unbedingt zu vermeiden,
daher sind auch andere Varianten nicht ganz auszuschließen

eine einfache, auch relativ saubere möchte ich noch nennen: der Thread malt auf ein Image-Objekt, dessen getGraphics() kann gerne herumgereicht werden,
paintComponent malt nur jederzeit das aktuellste Bild, gegen Flackern hilft das aber im Extremfall glaube ich auch nicht


ein Link, allerdings auch auf einfachem Niveau, unter 'Thread rechnet, paint malt'-Verfahren ohne dass Flacker-Probleme eine Rolle spielen, nehme ich an:
http://www.java-forum.org/spiele-multimedia-programmierung/54795-quaxli-2d-spiele-tutorial.html
 
Zuletzt bearbeitet von einem Moderator:

GUI-Programmer

Top Contributor
der Thread malt auf ein Image-Objekt, dessen getGraphics() kann gerne herumgereicht werden

Das wollte ich auch gerade sagen. Hier nen kleines Beispiel:
Java:
public class Xy extends JPanel {
	protected BufferedImage drawingImage;
	
	public Xy() {
		setPreferredSize(new Dimension(800, 600));
		drawingImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TRANSLUCENT);
		Graphics2D g2 = drawingImage.createGraphics();
		g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
		g2.fillRect(10, 10, 100, 100);
		// Du solltest bei deiner Thread-Klasse sonen Konstruktor erstellen, um eben
		// das Bild übergeben zu können, dass dann in der run() verändert werden kann
		DeinThread t = new DeinThread(drawingImage);
		t.start();
	}

	protected void paintComponent(Graphics g) {
        if (g instanceof Graphics2D) {
        	Graphics2D g2 = (Graphics2D)g;
        	g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
        	g2.drawImage(drawingImage, 0, 0, this);
        }
    }
}

Ach und ich glaube, dass es sinnvoller wäre, wenn deine Thread-Klasse nicht von Thread sondern von SwingWorker erbt.
 

lal000r

Mitglied
Danke für Eure Vorschläge, vielleicht muss ich dazu noch sagen, dass ich noch nicht sonderlich erfahren auf dem Gebiet der Anwendungsentwicklung bin, vor allem was die Umsetzung von Threads angeht, ist das meine Premiere ;)

der Thread muss sich für Graphics nicht interessieren, seine Berechnungen können unabhängig vom Zeichnen sein,
er bestimmt den aktuellen Zeitpunkt, berechnet meinetwegen Positionen usw., und dann folgt nur ein Befehl: repaint()
-> schon ist auf sauberen Wege irgendwann die paint-Methode dran, die nimmt sich was an Informationen nötig ist und malt exakt den aktuellen Zustand

Das "Problem" ist nur, dass die entsprechende Methode anhand der Panelgröße die Berechnungen durchführt. (Deswegen übergebe ich ja das Panel)
Ich bin mir ziemlich sicher, dass das momentan vorhandene Flackern durch das getGraphics() ausgelöst wird, weil ich wegen dem Problem hier schonmal einen Thread aufgemacht hatte. :)

GUI-Programmer:
Ich versuche zu verstehen, welchen Ansatz du mir da erläutern möchtest. Ich glaube, du erzeugst ein neues (eigenes) Graphics-Objekt, mit dem du dann malst?

Ich glaube, es wäre besser, wenn ich mal ein bisschen Code poste, damit wir nicht aneinander vorbeireden.

Eigentlich baut in der Panel-Klasse vieles auf den booleschen Variablen auf, die von Controllern gesetzt werden. Je nach Wert, werden die entsprechenden Methoden beim repaint() dann ausgeführt oder auch nicht.

Klasse des Panels:
Java:
public class BoardGraphic extends JPanel implements Observer {

	private static final long serialVersionUID = 1L;
	ActivePiece activepiece = null;
	boolean isDragging, isPressed, moveExecuted = false;
	final int CELLSIZE = 80;

	public BoardGraphic() {
		this.setPreferredSize(new Dimension(650, 600));
		this.setBackground(new Color(230, 230, 250));
		this.addMouseListener(new Mouselistener(this));
		this.addMouseMotionListener(new MousemotionListener(this));
		new BoardObserver(this);
	}
	
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		int xStart = this.getWidth() / 2;
		int yStart = this.getHeight() / 2;
		this.setFont(g);
		
		//Spielbrett
		for (int i = 0; i < 7; i++) {
			for (int j = 0; j < 7; j++) {
				if (i % 2 == 0) {
					if (j % 2 == 0) {
						g.setColor(new Color(105, 105, 105));
					} else {
						g.setColor(new Color(240, 230, 140));
					}
				} else {
					if (j % 2 == 0) {
						g.setColor(new Color(240, 230, 140));
					} else {
						g.setColor(new Color(105, 105, 105));
					}
				}
				g.fillRect(xStart - 280 + j * CELLSIZE, yStart - 280 + i * CELLSIZE, CELLSIZE, CELLSIZE);		
			}
		}
		// Zeilenbeschriftungen links
		for (int i = 1; i < 8; i++) {
			g.drawString(Integer.toString(i), xStart - 320, (yStart - 230) + (i - 1) * CELLSIZE);
		}
		// Zeilenbeschriftungen rechts
		for (int i = 1; i < 8; i++) {
			g.drawString(Integer.toString(i), xStart + 305, (yStart - 230) + (i - 1) * CELLSIZE);
		}
		//Spaltenbeschriftungen oben
		for (int i = 1; i < 8; i++) {
			char zwischen = (char) (i+96);
			g.drawString(Character.toString(zwischen), xStart-250 + (i-1)* CELLSIZE, yStart-310 );
		}
		//Spaltenbeschriftungen unten
		for (int i = 1; i < 8; i++) {
			char zwischen = (char) (i+96);
			g.drawString(Character.toString(zwischen), xStart-240 + (i-1)* CELLSIZE, yStart+320 );
		}
		
		drawPieces(g);
		IO.println("Repaint");
	
		
		if (this.isPressed && this.activepiece != null) {
			drawStartField(g);
			drawPossibleFields(g);
			
		}
		if (this.isDragging && this.activepiece != null){
			drawStartField(g);
			drawPossibleFields(g);
			drawHoveringField(g);
			drawPieceWhileDragging(this.activepiece.getDragX(), this.activepiece.getDragY(), g);
			}
		
		if (this.moveExecuted){
			IO.println("Animator");
			Animator anim = new Animator(this);
			anim.start()

		}
	}

Klasse Animator: (Ganz unten in der run mache ich das getGraphics)
Java:
public class Animator extends Thread {

	BoardGraphic panel;
	
	public Animator(BoardGraphic panel){
		this.panel=panel;
		
	}
	
	public void animateMove(int releasedX, int releasedY, Graphics g) {

		int xStart = panel.getWidth() / 2 - 280
				+ (panel.getActivepiece().getCol() * panel.CELLSIZE);
		int yStart = panel.getHeight() / 2 - 280
				+ (panel.getActivepiece().getRow() * panel.CELLSIZE);
		// Bestimmen der Model-Zielfelder der aktiven Spielfigur
		int[] pos = panel.getPositionOnBoard(releasedX, releasedY);
		int xEnd = panel.getWidth() / 2 - 280 + (pos[1] * panel.CELLSIZE);
		int yEnd = panel.getHeight() / 2 - 280 + (pos[0] * panel.CELLSIZE);

		// Horizontaler Abstand ist größer als vertikaler Abstand, zunächst horizontale,
		// dann vertikale Animation durchführen
		if (Math.abs(xEnd - xStart) > Math.abs(yEnd - yStart)) {
			verticalMove(yStart, yEnd, horizontalMove(xStart, xEnd, yStart, g), g);
		}
		
		// Vertikaler Abstand ist größer als horizontaler Abstand, zunächst vertikale, 
		// dann horizontale Animation durchführen
		else {
			horizontalMove(xStart, xEnd, verticalMove(yStart, yEnd, xStart, g), g);
		}
		panel.repaint();
		panel.setMoveExecuted(false);
	}
	
	//Animiert einen horizontalen Zug und gibt den aktuellen Wert von xStart zurück
	public int horizontalMove(int xStart, int xEnd, int yStart, Graphics g) {
		while (Math.abs(xEnd - xStart) > 0) {
			g.drawImage(panel.loadPieceImages(panel.activepiece.getPiece()), xStart,
					yStart, panel);
			if (xStart < xEnd) {
				xStart += 1;
			} else {
				xStart -= 1;
			}
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}panel.setMoveExecuted(false);
			panel.repaint();
		}
		return xStart;
	}
	//Animiert einen vertikalen Zug und gibt den aktuellen Wert von yStart zurück
	public int verticalMove(int yStart, int yEnd, int xStart, Graphics g) {
		while (Math.abs(yEnd - yStart) > 0) {
			g.drawImage(panel.loadPieceImages(panel.activepiece.getPiece()), xStart,
					yStart, panel);
			if (yStart < yEnd) {
				yStart += 1;
			} else {
				yStart -= 1;
			}
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}panel.setMoveExecuted(false);
			panel.repaint();
		}
		return yStart;
	}

	
	 public void run() {
		animateMove(panel.getActivepiece().getReleasedX(),panel.getActivepiece().getReleasedY(), panel.getGraphics());
	 }
	
}

Es mag ja auch sein, dass ich mit meinem Code völlig auf dem Holzweg bin ;) Danke für Eure Mühe!

Achja, danke für das Tutorial, ich werde es mir morgen mal genauer angucken.
 
Zuletzt bearbeitet:

lal000r

Mitglied
Achja, vielleicht sollte ich noch die Intention dessen bekanntgeben, weswegen ich versuche in einem extra Thread zu malen.

Der Zug der Spielfigur soll animiert erfolgen und das realisiere ich momentan so, dass ich nach jedem "Verschieben" der Figur nach x oder y den Thread für 20ms pausieren lasse. Wenn ich das in der Haupt-paintComponent-Methode versuche, hängt das komplette Spiel kurz und dann wird der Zug trotzdem blitzschnell ausgeführt.
 
S

SlaterB

Gast
das mag deine Intention sein, aber ist kein sinnvoller Grund,
paint malt einfach, fertig, leichter könnte es nicht sein,
paint malt weder mehrfach, noch wartet es, noch muss es die Zeit für Berechnungen nutzen,
all das macht der Thread und wann immer der es für nötig hält zu zeichnen, z.b. vor den 20ms Warten, ruft er repaint() auf,
einfach und sauber, vom Flackern abgesehen
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
C Graphics Objekt in Zeitschleife zeichnen AWT, Swing, JavaFX & SWT 4
V 2D-Grafik Frage zum Graphics Objekt AWT, Swing, JavaFX & SWT 2
Furtano AWT paint braucht ein Graphics Objekt ? AWT, Swing, JavaFX & SWT 2
S Unterscheiden ob ein Graphics-Objekt von einer JComponent oder einem BufferedImage kommt..? AWT, Swing, JavaFX & SWT 4
M Graphics-Objekt aktualisiert sich nicht AWT, Swing, JavaFX & SWT 2
K Graphics-Objekt zeichnet nicht alle Bilder AWT, Swing, JavaFX & SWT 3
N Graphics Objekt "puffern" AWT, Swing, JavaFX & SWT 7
R Graphics Objekt ändern AWT, Swing, JavaFX & SWT 11
R Selectable Graphics Objekt gesucht. AWT, Swing, JavaFX & SWT 5
Wildcard FontMetrics ohne Graphics-Objekt AWT, Swing, JavaFX & SWT 13
A Problem mit dem graphics-Objekt AWT, Swing, JavaFX & SWT 8
N Graphics Objekte scalen mit Veränderung des Bildschirms AWT, Swing, JavaFX & SWT 19
T Bild in ein graphics füllen AWT, Swing, JavaFX & SWT 2
volcanos Scrollen: JScrollPane mit Graphics g und Java-Fonts extends Frame ? AWT, Swing, JavaFX & SWT 5
DonBronson Java Graphics bewegbar machen (Drag&Drop) AWT, Swing, JavaFX & SWT 3
ExceptionOfExpectation MouseListener-Objekte zu den Graphics-Objekten einfügen AWT, Swing, JavaFX & SWT 3
R AWT Graphics initialisieren AWT, Swing, JavaFX & SWT 15
P JPanle, JFrame und Graphics AWT, Swing, JavaFX & SWT 2
R 2D-Grafik PNG Bild per Graphics auf JPanel AWT, Swing, JavaFX & SWT 9
B Graphics to Image AWT, Swing, JavaFX & SWT 3
T Swing Graphics auf Panel AWT, Swing, JavaFX & SWT 2
B Graphics -> Graphics2D etwas zu beachten? AWT, Swing, JavaFX & SWT 8
P ActionListener Graphics Einbauen AWT, Swing, JavaFX & SWT 0
J Swing Problem mit Graphics Methode AWT, Swing, JavaFX & SWT 4
R Swing Bewegung eines Graphics Objektes innerhalb eines JPanels funktioniert nicht richtig AWT, Swing, JavaFX & SWT 2
V Netbeans: TabbedPane, ScrollPane und Graphics AWT, Swing, JavaFX & SWT 4
V Graphics g - drawOval problem mit background AWT, Swing, JavaFX & SWT 1
M Graphics.fillOval AWT, Swing, JavaFX & SWT 1
javampir Sauberes Faden mit awt Graphics AWT, Swing, JavaFX & SWT 6
D 2D-Grafik Inhalt eines Graphics in anderes Graphics zeichnen.... AWT, Swing, JavaFX & SWT 3
X AWT Text der mit Graphics "drawString(...)" geschreiben wurde wieder löschen. AWT, Swing, JavaFX & SWT 6
C Zwei Ebenen in Graphics ? AWT, Swing, JavaFX & SWT 0
D Frage zu JFrame und Graphics AWT, Swing, JavaFX & SWT 4
I JavaFX Graphics Performance AWT, Swing, JavaFX & SWT 2
vodkaz Graphics aufrufen AWT, Swing, JavaFX & SWT 4
P 2D-Grafik NPE beim Zeichnen auf Graphics g AWT, Swing, JavaFX & SWT 8
M Graphics.drawImage von unten nach oben abbilden lassen AWT, Swing, JavaFX & SWT 6
F Probleme mit (Graphics g) II AWT, Swing, JavaFX & SWT 4
F Probleme mit (Graphics g) AWT, Swing, JavaFX & SWT 3
M JFrame Graphics.drawString Problem AWT, Swing, JavaFX & SWT 11
I Rechteck eines Graphics eines JPanels in einem anderen JPanel anzeigen AWT, Swing, JavaFX & SWT 7
antonbracke Multiplayer Shooter- Wie geht das mit Canvas & Graphics AWT, Swing, JavaFX & SWT 6
R Ankerpunkt bei Graphics AWT, Swing, JavaFX & SWT 3
R Fließende Bewegung von Graphics AWT, Swing, JavaFX & SWT 6
T AWT Graphics G Kein Text erscheint warum? AWT, Swing, JavaFX & SWT 12
L Graphics.drawImage() - Output-Größe entspricht nicht Parametern AWT, Swing, JavaFX & SWT 10
L Border verschwindet durch Graphics.drawImage() AWT, Swing, JavaFX & SWT 4
P "Graphics" wird nicht angezeigt AWT, Swing, JavaFX & SWT 11
B Swing Zeilenumbruch in Graphics AWT, Swing, JavaFX & SWT 20
T Graphics zeichnet nicht AWT, Swing, JavaFX & SWT 2
T Applet graphics - zeichnen funktioniert nicht AWT, Swing, JavaFX & SWT 14
R Graphics-Object speichern AWT, Swing, JavaFX & SWT 4
S Zeichnen mit java.awt.Graphics AWT, Swing, JavaFX & SWT 6
D Graphics zeichnen AWT, Swing, JavaFX & SWT 6
M Graphics auf JFrame Koordinatensystem AWT, Swing, JavaFX & SWT 3
T Graphics Ersetzend Zeichnen AWT, Swing, JavaFX & SWT 6
Developer_X Swing Auf ein BufferedImage mit Graphics/Graphics2D zeichnen AWT, Swing, JavaFX & SWT 6
D Erzeugen eines leeren Graphics-Objektes AWT, Swing, JavaFX & SWT 7
B Anzeigefehler in GridBagLayout durch paintComponent(Graphics g) AWT, Swing, JavaFX & SWT 3
A AWT AWT Panelfenster mit Graphics kombinieren AWT, Swing, JavaFX & SWT 7
T Graphics Parameterübergabe AWT, Swing, JavaFX & SWT 3
K Graphics.drawImage() sehr schnell AWT, Swing, JavaFX & SWT 5
N paintComponent für Graphics ansprechen AWT, Swing, JavaFX & SWT 2
M Graphics.drawImage verlangsamt sich plötzlich AWT, Swing, JavaFX & SWT 15
S Swing AWT (graphics (g)) AWT, Swing, JavaFX & SWT 27
E einfache Frage zu paintComponent und Graphics AWT, Swing, JavaFX & SWT 7
B Swing Tooltips auf Graphics AWT, Swing, JavaFX & SWT 8
Ä Graphics-Komponente auf JPanel wird nicht angezeigt AWT, Swing, JavaFX & SWT 4
S Applet mit Graphics dynamisch vergrößern AWT, Swing, JavaFX & SWT 3
T Dialog ohne Frame, direktes paint in graphics AWT, Swing, JavaFX & SWT 5
T Swing Component in Graphics zeichnen AWT, Swing, JavaFX & SWT 4
J getFontMetrics außerhalb von paint(Graphics g) AWT, Swing, JavaFX & SWT 8
E Problem bzw. Sinn von Graphics / Graphics Context AWT, Swing, JavaFX & SWT 21
S Weder ActionListener noch Graphics wollen so recht AWT, Swing, JavaFX & SWT 3
F Methode drawOval(int,int,int,int) von graphics AWT, Swing, JavaFX & SWT 4
G Graphics Objekte in AWT Container einfügen AWT, Swing, JavaFX & SWT 2
S Mit Graphics g ins Fenster zeichnen AWT, Swing, JavaFX & SWT 4
G Graphics - Raute AWT, Swing, JavaFX & SWT 3
G "pinseldicke" bei Graphics? AWT, Swing, JavaFX & SWT 2
G Graphics.drawImage() AWT, Swing, JavaFX & SWT 6
D Methode Graphics g klassenübergreifend nutzen. AWT, Swing, JavaFX & SWT 3
W java.lang.NoClassDefFoundError: org/eclipse/swt/graphics/Dev AWT, Swing, JavaFX & SWT 1
B Graphics und Canvas - Problem AWT, Swing, JavaFX & SWT 2
H eigene paintComponent(Graphics) kommt mit rezise nicht klar AWT, Swing, JavaFX & SWT 6
T Transparenz bei Graphics AWT, Swing, JavaFX & SWT 9
L Graphics AWT, Swing, JavaFX & SWT 37
B JPanel#paintComponent(Graphics g) << flackert oO AWT, Swing, JavaFX & SWT 3
Y Problem mit der Referenz eines Graphics-Objekts AWT, Swing, JavaFX & SWT 5
O Graphics erstellt Componente scheinbar nicht richtig AWT, Swing, JavaFX & SWT 23
G 2x Graphics in einer paint() miteinander verbinden AWT, Swing, JavaFX & SWT 11
K Gutes Buch gesucht (Graphics Only) Kennt jemand eins? AWT, Swing, JavaFX & SWT 5
J Einmal gleichzeitig auf zwei Graphics malen? AWT, Swing, JavaFX & SWT 5
E Image, Graphics, verzögert zeichnen AWT, Swing, JavaFX & SWT 2
H neuzeichnen von graphics nach minimierung oder ähnlichem AWT, Swing, JavaFX & SWT 10
G SWT Graphics Zeichnung neu laden AWT, Swing, JavaFX & SWT 13
G SWT Graphics GC Problem AWT, Swing, JavaFX & SWT 6
M Abstrakte Graphics Klasse erzeugen AWT, Swing, JavaFX & SWT 2
H awt Graphics und Image selbermachen ? AWT, Swing, JavaFX & SWT 12
D Image aus Graphics erstellen? AWT, Swing, JavaFX & SWT 2
raptorrs J2D graphics, sind 500px immer 500 px AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben