AWT Graphics G Kein Text erscheint warum?

Terep

Mitglied
Ich habe hier eine Testanwendung für den KeyListener.
Das funktioniert auch.
Was mich beschäftigt, ist Graphics g.
Warum erscheint kein Text? Keine Fehlermeldung.

Java:
import java.awt.*;
import java.awt.event.*;

public class Grafikbeispiel implements KeyListener
{

	Frame frame;
	Font font;
		
	public Grafikbeispiel()
	{
		frame = new Frame("Testgrafik");
		frame.setSize(300, 200);
		frame.setVisible(true);
		frame.addKeyListener(this);
		frame.repaint();
	}
	
	public void paint (Graphics g)
	{
		font = new Font ("SansSerif", Font.PLAIN, 36);
		g.drawString(" ESC für Beenden", 150, 150);
	}
	
	public void keyPressed(KeyEvent event) 
	{
		if (event.getKeyCode() == KeyEvent.VK_ESCAPE)
		{
			frame.setVisible(false);
			frame.dispose();
			System.exit(0);
		}
	}
	
	public void keyReleased(KeyEvent event) { }
	
	public void keyTyped(KeyEvent event) { }
}

und die TestMain:
Java:
public class StartMain 
{
	public static void main(String[] args) 
	{
		new Grafikbeispiel();
		
	}

}

Graphics kriege ich einfach nicht in den Griff.
Die Tutorials habe ich schon durch.

Entweder baue ich ein Spielfeld, dann habe ich kein Zugriff per Spiellogik.
Oder ich habe Spiellogik, aber keine Grafik.

Dies konkret habe ich noch nicht verstanden.

Daher die Frage, warum kommt hier kein Grafiktext.
Vielleicht gibt die Antwort einen Einstieg.

Terep
 

L-ectron-X

Gesperrter Benutzer
paint(Graphics g) ist eine Methode aus [JAPI]Component[/JAPI].
Das heißt, wenn die Methode etwas zeichnen soll, muss sie in einer entsprechenden Klasse, die von Component erbt, überschrieben werden.

in paint() sollten auf keinen Fall Klassen instanziiert werden!
 

Marco13

Top Contributor
Hm. Das klingt schon ein bißchen ZU drastisch :) Man sollte möglichst wenig rechnen und allokieren, und die Erzeugung des Fonts steht da schon arg verloren rum, aber ums Instantiieren kommt man ja kaum drumrum.
 

L-ectron-X

Gesperrter Benutzer
aber ums Instantiieren kommt man ja kaum drumrum.
Das mag schon sein, aber auf keinen Fall in der paint()-Methode.
Ich würde den Font im Konstruktor erzeugen und in einer privaten Instanzvariable speichern.
Die paint()-Methode würde dann z.B. so aussehen:
Java:
public void paint (Graphics g) {
    super.paint(g);
    g.setFont(font);
    g.drawString("ESC für Beenden", 150, 150);
}

Anderenfalls würde bei jedem Zeichendurchgang (und das können sehr viele hintereinander sein) ein Font-Objekt erstellt werden - ziemlich unperformant.
 

Marco13

Top Contributor
Ja, das mit dem Font ist klar (vor allem weil man nicht abschätzen kann, WIE aufwändig das Erzeugen eines Fonts ist). Aber GAR keine Objekterzeugung wird schwierig... ;) Sowas wie
g.draw(new Line2D.Double(p0, p1));
ist ja relativ unkritisch...
 

Terep

Mitglied
Danke für die Reaktionen. Leider noch nicht geklärt

Wenn ich wie vorgeschlagen, < super paint (g); > einsetze, kommt eine Fehlermeldung.
Die verschwindet erst, wenn ich extends Frame einsetze. Dann ist zwar der Fehler weg, die Graphics g findet wohl nicht das frame.
Java:
import java.awt.*;
import java.awt.event.*;

public class Grafikbeispiel extends Frame
{
	public Grafikbeispiel()
	{
		super("Testgrafik");
		setSize(300, 200);
		setVisible(true);
		addKeyListener(
				new KeyAdapter(){
					public void keyPressed(KeyEvent event) 
					{
						if (event.getKeyCode() == KeyEvent.VK_ESCAPE)
						{
							setVisible(false);
							dispose();
							System.exit(0);
						}
					}
				});
		repaint();  // keine Funktion
	}
	
	public void paint (Graphics g)
	{
		super.paint(g);  // nicht nötig
		g.drawString(" ESC für Beenden", 150, 150);
	}
}

Es geht natürlich sofort, wenn ich dann aus frame erbe und nicht mit new Frame progge:
Java:
import java.awt.*;
import java.awt.event.*;

public class Grafikbeispiel extends Frame
{
	public Grafikbeispiel()
	{
		super("Testgrafik");
		setSize(300, 200);
		setVisible(true);
		addKeyListener(
				new KeyAdapter(){
					public void keyPressed(KeyEvent event) 
					{
						if (event.getKeyCode() == KeyEvent.VK_ESCAPE)
						{
							setVisible(false);
							dispose();
							System.exit(0);
						}
					}
				});
		//repaint();  // keine Funktion
	}
	
	public void paint (Graphics g)
	{
	//	super.paint(g);   nicht nötig
		g.drawString(" ESC für Beenden", 150, 150);
	}
}


Die Frage, die mich treibt, warum nicht. Hier habe ich etwas nicht verstanden, was mich darin hindert Graphics g „normal“ einzusetzen. Das heißt, ich will in einer weiteren Datei Spiellogik für ein Brettspiel entwickeln und muss daher regelmäßig Graphics g bemühen.

Kann mir einer sagen, wie ich ohne extends Frame Graphics g einbinde. Muß ich wie im Hubschraubertutorial ein Interface einsetzen? Kein Fehler, leider auch keine Grafik.
Java:
import java.awt.Graphics;

public interface Drawable {
	public void drawObjects (Graphics g);
}

und dann wie folgt nutzen:
Java:
import java.awt.*;
import java.awt.event.*;

public class Grafikbeispiel extends Frame implements Drawable //ohne extends Fehler bei super.paint(g);
{
	Frame frame;
	public Grafikbeispiel()
	{
		frame = new Frame("Testgrafik");
		frame.setSize(300, 200);
		frame.setVisible(true);
		frame.addKeyListener(
				new KeyAdapter(){
					public void keyPressed(KeyEvent event) 
					{
						if (event.getKeyCode() == KeyEvent.VK_ESCAPE)
						{
							frame.setVisible(false);
							frame.dispose();
							System.exit(0);
						}
					}
				});
		frame.repaint();  // keine Funktion
	}
	
	public void drawObjects (Graphics g)
	{
		super.paint(g);
		g.drawString(" ESC für Beenden", 150, 150);
	}
}

Wie gesagt, ich habe Umsetzungsprobleme in der Art, dass ich mit Graphics g ein Spielbrett malen kann, habe aber dann Probleme, aus der Spielschleife heraus Graphics g pro Schleifengang zu aktivieren. Daher hoffe ich, dass ich hiermit der Sache auf der Spur bin.

Terep
 

Harry Kane

Top Contributor
Zu der Aussage
Wenn ich wie vorgeschlagen, < super paint (g); > einsetze, kommt eine Fehlermeldung.
Die verschwindet erst, wenn ich extends Frame einsetze. Dann ist zwar der Fehler weg, die Graphics g findet wohl nicht das frame.
was soll die letzte Aussage "die Graphics g findet wohl nicht das frame" bedeuten?
Wenn du super.paint(Graphics g) aufrufst, prüft der Compiler, ob in der Oberklasse eine Methode mit dem angebenen Namen und er Signatur existiert. Ohne "extends Frame" erbt deine Klasse direkt von java.lang.Object, und die hat keine paint-Methode. Deshalb gibt der Compiler eine Fehlermeldung raus.

Wenn du das "extends Frame" und "super.paint()" weglässt, kompiliert zwar der Code, aber deine paint() Methode wird nicht aufgerufen. Von wem auch?
Du brauchst anscheinend zwei Dinge:
1. Ein Grafikobjekt, was nix mit Component, Frame usw. zu tun hat, sondern einfach irgendwas auf einen Graphics zeichnet.
2. Ein spezielles Frame, Component, JComponent (letzteres würde ich dir stark empfehlene. Lass AWT AWT sein, und programmiere in Swing), welches Du in einen JFrame einbettest und welches in seiner paintComponent(Graphics g) nichts anderes macht, als das "Grafikobjekt" aus 1. zu zeichnen.
Ich habe hier mal einen kleine Demo zusammengehackt:
Java:
public class GrafikPanel extends JComponent
{
    GrafikObjekt go = new GrafikObjekt();
    public void paintComponent (Graphics g)
    {
        go.zeichneDich(g);
    }
    public static void main(String[] args){
     final JFrame frame = new JFrame("Grafik Test");
     frame.addKeyListener(
                new KeyAdapter(){
                    public void keyPressed(KeyEvent event)
                    {
                        if (event.getKeyCode() == KeyEvent.VK_ESCAPE)
                        {
                            frame.setVisible(false);
                            frame.dispose();
                            System.exit(0);
                        }
                    }
                });

     GrafikPanel gp = new GrafikPanel();
     gp.setPreferredSize(new Dimension(300, 300));
     frame.setContentPane(gp);
     frame.pack();
     frame.setVisible(true);

     GrafikPanel bsp = new GrafikPanel();
    }
}
class GrafikObjekt{
    public void zeichneDich (Graphics g)
    {
        g.drawString(" ESC für Beenden", 150, 150);
    }

}
 

L-ectron-X

Gesperrter Benutzer
Eigentlich zeichnet man nicht direkt in (J)Frames.
In AWT, dessen GUI-Komponenten inzwischen als veraltet gelten, zeichnet man in von Panel oder Component abgeleitete Klassen.
In Swing entsprechend in von JPanel oder JComponent abgeleitete Klassen. Hier wird aber nicht die paint()-, sondern die paintComponent()-Methode zum Zeichnen überschrieben.

Der super-Aufruf der Zeichenmethode der jeweiligen Basisklasse ist zwingend notwendig, um den Hintergrund der Basisklasse zu zeichnen. U.U. kommt es sonst zu unerwarteten Fehlverhalten.
 

Terep

Mitglied
Zuerst einmal finde ich es beeindruckend, wie schnell hier Statements kommen und der Wille zum Helfen ist spürbar, dafür danke. Leider trete ich schon eine ganze Weile auf der Stelle. Irgendwie nervig, ich kann das Spiel auf der Konsole ohne Grafik proggen, kriege es aber einfach nicht ins Bild.

Nun, ich habe versucht den Faden aufzunehmen. Die Erklärung von Harry Kane schätze ich als kompetent ein und kann es im Wesentlichen nachvollziehen aber leider nicht weiterentwickeln.

Mein Endziel ist es, ein Brettspiel nachzuprogrammieren.
Ich habe es im Quellcode angedeutet.
Java:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.Graphics;

public class GrafikPanel extends JComponent
{
    GrafikObjekt go = new GrafikObjekt();
    public void paintComponent (Graphics g)
    {
        go.initFeld(g);
    }
    public static void main(String[] args){
     final JFrame frame = new JFrame("Grafik Test");
     frame.addKeyListener(
                new KeyAdapter(){
                    public void keyPressed(KeyEvent event)
                    {
                        if (event.getKeyCode() == KeyEvent.VK_ESCAPE)
                        {
                            frame.setVisible(false);
                            frame.dispose();
                            System.exit(0);
                        }
                    }
                });
 
     GrafikPanel gp = new GrafikPanel();
     gp.setPreferredSize(new Dimension(500, 200));
     frame.setContentPane(gp);
     frame.pack();
     frame.setVisible(true);
 
     GrafikPanel bsp = new GrafikPanel();
    }
}
und
Java:
import java.awt.Graphics;

class GrafikObjekt{
    public void initFeld (Graphics g)
    {
int xx, xd, yy, yd, sx, sy;
		
		xx =  10;
		yy =  40;
		sx =  80; // doppelte Feldbreite
		sy =  80; 
			
		g.drawRect (xx, yy, sx, sy);
		xx = xx + sx;
		sx =  40; // Feldbreite
		g.drawRect (xx, yy, sx, sy);
		g.drawString ("Start", xx-50, yy+15);
	
		for ( int i = 0; i < 8; i++)
		{
			g.drawString ("Pos "+ (i+1), xx+5, yy+15);
			g.drawRect (xx, yy, sx, sy);
			xx = xx + sx;
			
		}
		
    }
 }

Das Spielfeld zu malen, ist kein Problem. Aber wie bekomme ich die anfallenden Grafikarbeiten aus der Spielschleife in Laufen?
Das heißt, Spielfiguren bewegen sich, Spielfelder ändern sich usw..

Konkrete Frage. Wo und wie kann ich aus einer Spielschleife mit unterschiedlichen Grafikaufgaben ins Geschehen greifen?

Terep
 

Marco13

Top Contributor
So konkret ist das gar nicht.

Aus der "Spielschleife" heraus zeichnet man üblicherweise nicht direkt. In der Spielschleife (die vom Haupt-Thread ausgeführt wird) werden die Zustände von Objekten verändert. In der Klasse, die für's zeichnen zuständig ist, liegen entweder die Objekte selbst, oder irgendwas, was anstelle der Objekte gezeichnet werden soll. Und das macht sie - NUR von der paintComponent-Methode aus.
 

Terep

Mitglied
Das habe ich befürchtet. Graphics g ist wirklich keine normale Methode.
Harry Kane hat es ja in einem oberen Posting auch schon angerissen.

Ich habe mich bis jetzt viel mit der Konsole beschäftigt und erst wenig mit der GUI. In der GUI passieren all die Sachen, von denen ich vorher gesagt habe, brauche ich eigentlich nicht.

OK, zur Sache. Die Spielschleife wird in einem Thread eingebettet, Die Spielschleife ruft unter anderem die Klasse Tu_was_mit_Grafik aus. Von dort müssen die entsprechenden Infos so übergeben werden, dass Graphics g ins Arbeiten kommt.

Bildlich gesprochen bin ich nicht mehr in einer Sackgasse. Vielmehr doch, ich muss die Sackgasse verlassen und mich mehr mit der GUI beschäftigen. Das werde ich tun.
Da es keine einfache klare Lösung gibt, werde ich diesen Beitrag als erledigt markieren.

Harry Kane, danke für die inhaltliche Auseinandersetzung und Marco für die Hinweise, in welche Richtung es geht.

Terep
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
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
C Graphics Objekt in Zeitschleife zeichnen AWT, Swing, JavaFX & SWT 4
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
V 2D-Grafik Frage zum Graphics Objekt AWT, Swing, JavaFX & SWT 2
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
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
Furtano AWT paint braucht ein Graphics Objekt ? AWT, Swing, JavaFX & SWT 2
P "Graphics" wird nicht angezeigt AWT, Swing, JavaFX & SWT 11
L Graphics Objekt - aus anderer Klasse aufrufen / übergeben AWT, Swing, JavaFX & SWT 5
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
S Unterscheiden ob ein Graphics-Objekt von einer JComponent oder einem BufferedImage kommt..? AWT, Swing, JavaFX & SWT 4
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
M Graphics-Objekt aktualisiert sich nicht AWT, Swing, JavaFX & SWT 2
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
K Graphics-Objekt zeichnet nicht alle Bilder AWT, Swing, JavaFX & SWT 3
J Einmal gleichzeitig auf zwei Graphics malen? AWT, Swing, JavaFX & SWT 5
E Image, Graphics, verzögert zeichnen AWT, Swing, JavaFX & SWT 2
N Graphics Objekt "puffern" AWT, Swing, JavaFX & SWT 7
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
R Graphics Objekt ändern AWT, Swing, JavaFX & SWT 11
raptorrs J2D graphics, sind 500px immer 500 px AWT, Swing, JavaFX & SWT 2
G Graphics AWT, Swing, JavaFX & SWT 2
H Graphics: Schriftgröße ändern AWT, Swing, JavaFX & SWT 4
X Problem mit Image und Graphics AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben