Java Verständnisfrage Graphics/Zeichnen

Elcrian

Commander
Registriert
Feb. 2008
Beiträge
2.493
Hallo,
ich habe eine Simulation programmiert und per Eclipse-Plugin eine GUI erzeugt. Die macht nicht viel mehr als manuell ohne Layout Manager die Items zu platzieren und auf Wunsch mit einem ActionListener zu versehen.
Nun möchte ich zu dieser Simulation eine einfache, grafische Oberfläche hinzufügen die zu jedem Simulationselement (es geht übrigens um Roulette) einen Punkt hinzufügt, möglichst auf einer variablen Achse.

Nur scheitert es schon am Zeichnen eines weißen Hintergrundes. :freak:
Die Grundidee der Java-SWING-Oberfläche (kann es übrigens sein das die wahnsinnig träge ist? Die Simulation läuft mit GUI elendig langsam...) ist ja soweit ich das verstanden habe "Frame -> Elemente -> ActionListener". Zeichnen geht ja per Graphics-Instanz.
Daher dachte ich mir mit Hilfe vom Internet: Zwei innere Klassen, eine die als "LayeredPane" ein zusätzliches Panel (InnerPanel) auf dem Fenster integriert.

Nur wirft es bei mir vor dem Zeichnen einen NullPointer.
Exception in thread "main" java.lang.NullPointerException
at GUI$InnerPanel.paintComponent(GUI.java:140)


Code, ohne den restlichen Kram runter rationalisiert:
PHP:
import javax.swing.*;

public class GUI extends start implements ActionListener {

private Graphics gg;


	public GUI() {
		JFrame f = new JFrame(); 		// Fenster-Objekt
				
		// Zeichenarea
		MyLayered panel = new MyLayered();
		f.getContentPane().add(panel);
		f.setBounds(306, 6, 799, 656);
		f.setVisible(true);
		//f.setDefaultCloseOperation(J.Frame.EXIT_ON_CLOSE);
		 //panel.paintComponent(gg);
				
	}	
	
	class InnerPanel extends JPanel {
	 InnerPanel() {
		 this.paintComponent(gg);
	 }	
		public void paintComponent(Graphics gg) {
		Graphics2D g2 = (Graphics2D)gg;
		gg.setColor(Color.WHITE);
		gg.fillRect(306, 6, 799, 656);
	 }
	}
	
	class MyLayered extends JLayeredPane{
	  MyLayered() {
	    this.add(new InnerPanel(), 14);
	  }

Wie löse ich das? Ich fürchte ich blicke bei dem GUI-Krams nicht so 100% durch...

Danke!
 
Warum nicht einfach eine neue Klasse schreiben und die Paint-Methode überschreiben?

Ich habe auch immer JFrames benutzt und dann JPanels mit geänderter Paint-Methode eingezetzt um spezifischen content zu zeichen, wie gespiegelte Bilder oder so, hat bei mir immer einwandfrei funktioniert.

Code:
public class Dingens extends JPanel {

@Override
	public void paint(Graphics g) {
		g.setColor(Color.WHITE);
		g.drawRect(0,0,200,200);
	}
	
}

Edit: Ich glaub dein Fehler liegt darin, dass du die Paint-Methode nicht überschreibst sondern eine neue schreibst...
 
Zuletzt bearbeitet:
"gg" wird, soweit ich das sehe, niemals initialisiert. Du versuchst aber es zu benutzen, um zu zeichnen. Du brauchst das aber auch überhaupt nicht initialisieren, nicht einmal anlegen. Wenn du eine der paint-Methoden überschreibst, bekommt sie automatisch ein Graphics-Objekt übergeben.
 
Zuletzt bearbeitet:
Habe ich dann so gemacht:
PHP:
// Zeichenarea
		panel = new InnerPanel();
		f.getContentPane().add(panel);
		f.setBounds(306, 6, 800, 650);

PHP:
	public class InnerPanel extends JPanel {

		@Override
			public void paintComponent(Graphics gg) {
			    Graphics2D g2 = (Graphics2D) gg;
				gg.setColor(Color.white);
				System.out.println("test");
				gg.fillRect(306, 6, 799, 656);
			}
			
		}

Nur wird nie gezeichnet, auch nicht bei Aufruf von panel.repaint();

Ich bräuchte je eine Klasse pro Zeichenanweisung, oder?
Ich muss ja auch die einzelnen Punkte des Graphen noch übergeben können und paintComponent(Graphics) mit mehr Parametern gibt es ja nicht. Ich bräuchte also eine überschriebene paintComponent-Methode und eine Art setCords(int x, int y);-Methode, am besten noch in einer eigenen "GraphCoords"-Klasse?
 
Ohne das Gesamtwerk zu kennen, ist das alles etwas schwierig zu beantworten.
Wird "test" denn ausgegeben?

Code:
[COLOR=#000000][COLOR=#0000bb]f[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]setBounds[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]306[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]6[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]800[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]650[/COLOR][COLOR=#007700]);  [/COLOR][/COLOR]
macht mir den Eindruck, dass es nicht das tut, was du davon erwartest. Der Frame ist doch dein Fenster (und da sollte ja nichts drüber stehen in deiner Hierarchie, oder?). Warum soll er dann gerade bei (306/6) gezeichnet werden? Klar, kann man so machen, es wundert mich nur, dass du da so seltsam präzise Werte setzt. Suggeriert, dass du eigentlich etwas anderes bezwecken willst.

Deiner eigentlichen Zeichenfläche, dem Panel, gibst du aber keinerlei Größe mit. Das könntest du in dessen Konstruktor machen. Um direkt zu sehen, ob dein Panel an der richtigen Stelle landet, kannst du testweise dem Hintergrund eine Farbe geben.

Das getContentPane() kannst du dir beim Hinzufügen des Panels zum Frame übrigens sparen.

Zum Übergeben der Punkte legst du in der Panel-Klasse einfach ein Feld an, welches du über eine Setter-Methode zugänglich machst. Dadurch kannst du von woanders (wo eben das Panel bekannt ist) über den Setter die aktuellen Punkte speichern. Die paint-Methode benutzt dann einfach die aktuell gesetzten in dem Feld ihrer Klasse. Dabei ist immer wichtig auf != null zu checken.
 
Zuletzt bearbeitet:
So schauts wohl aus. Versuche auch mal die Komponente dem JFrame hinzuzufügen bzw. einem Container und nicht über getContentPane() zu gehen...
 
Das war echt nicht pfiffig... muss natürlich...
PHP:
// Zeichenarea
		panel = new InnerPanel();
		f.getContentPane().add(panel);
		panel.setBounds(100, 6, 1050, 650);
...sein.

Somit hab ich schon einmal ein hübsches, weißes Feld. Das ist ein Anfang, danke schon einmal.
 
Zurück
Oben