# drawLine() auf JFrame funktioniert nicht



## juligo (8. Apr 2010)

Hallo, 
Ich habe mir eine GUI zusammengebastelt (3 Buttons auf einem JFrame) und möchte nun über diese Buttons eine Linie zeichnen.
Dazu habe ich mir im openBook "Java ist auch eine Insel" die Methode paint(Graphics g) herausgesucht. Allerdings dann in Foren gelesen, das man besser die Methode paintComponent(Graphics g) überschreiben solle. 
Das habe ich dann auch folgendermaßen in meinen Code eingebaut

GUI

```
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics.*;
import java.util.*;
import javax.swing.JFrame.*;

public class gui extends JFrame
{
	
	JFrame jf;
	JButton start, pause, stop;
	JLabel test;
	Graphics bg;
		
	public gui()
	{
		jf=new JFrame();
		jf.setTitle("");
		jf.setSize(370,500);	
		Container pane=jf.getContentPane();
		
		start = new JButton("Start");
		start.setSize(100, 40);
		start.setLocation(10, 420);
		pane.add(start);
		
		pause = new JButton("Pause");
		pause.setSize(100, 40);
		pause.setLocation(130, 420);
		pane.add(pause);
		
		stop = new JButton("Stop");
		stop.setSize(100, 40);
		stop.setLocation(250, 420);
		pane.add(stop);
		
		JLabel trash = new JLabel();
		trash.setSize(1,1);
		trash.setLocation(1,1);
		pane.add(trash);
		
		jf.setDefaultCloseOperation(jf.EXIT_ON_CLOSE);
		jf.setVisible(true);
		
		//paintComponent(bg);
		
	}
	
	
	public void paintComponent(Graphics g)
	{	
		super.paint(g);
     	g.drawLine(0,390,360,390);				
	}
}
```

"startup"-Klasse

```
import javax.swing.*;

public class startup
{
	public static void main (String[] args)
	{
		JFrame frame = new gui();
	}
}
```

starte ich nun meine startup-Klasse wird mein Frame mit den Buttons ganz normal angezeigt, jedoch wird die Linie nicht gezeichnet. Das habe ich mir erklärt, da ich ja nur den ?Konstruktor? gui aufrufe und dort halt nur die mir gezeigten Objekte erstellt werden. Also dachte ich ruf ich einfach dort die Methode paintComponent() auf. 
Starte ich nun meine startup-Klasse wird wieder nur mein Frame+Komponenten gezeichnet und zusätzlich in der Dos-Box die Meldung



> Exception in thread "main" java.lang.NullPointerException
> at gui.paintComponent(gui.java:54)
> at gui.(init)(gui.java:46)
> at test.main(startup.java:7)



Auch das habe ich "gegooglet" und gelesen, dass versucht wird auf eine Objektreferenz zuzugreifen, die den Wert null besitzt. Ich denke es handelt sich hier dann um mein Graphics-Objekt g. Als Lösung stand da "mit dem new-Operator initialisieren". 
Aber das geht doch nicht, oder!? Graphics ist doch abstract.

Kann mir wer Tipps geben?
Oder Hilfen wo ich nochmal drüber schauen könnte?

Ich möchte keine fertigen Lösungen, weil so verstehe ich das nicht und bin auch bei meinem Lernerfolg nicht weiter fortgeschritten. Aber ein Denkanstoß in die richtige Richtung wäre nett.

Danke & Gruß
Julian


----------



## SlaterB (8. Apr 2010)

puh, das wird ja ne Aufgabe

erstmal ganz offensichtlich:
du erzeugst  jf=new JFrame();
außedem ist noch das aktuelle gui-Objekt ein JFrame, da es von JFrame erbt
-> zwei JFrames, das kann nicht gut gehen

Swing-spezifisch:
NIE selber paintComponent aufrufen, das macht repaint(), dann bekommst du auch ein fertiges Graphics-Objekt übergeben,
kompliziert erzeugt aber das muss dich nicht interessieren

auf einem JFrame selber malt man generell gar nicht, höchstens auf einem JPanel, welches eingefügt wird,

mehr oder weniger könntest du mit diesem Tipps weiterkommen,
falls du doch eine Anleitung zur Umgehung all der tausend anderen möglichen Fehlern möchtest, siehe z.B.:

http://www.ralf-bauer.org/java/tutorial/Tutorial.zip


----------



## eRaaaa (8. Apr 2010)

juligo hat gesagt.:


> Allerdings dann in Foren gelesen, das man besser die Methode paintComponent(Graphics g) überschreiben solle.




Richtig, aber von JPanel, das steht aber auch so im Openbook(Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 17 Grafikprogrammierung)

Probier also mal

```
JPanel pane = new JPanel() {
	    @Override
	    protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawLine(0, 390, 360, 390);
	    }

	};
	jf.add(pane); //bzw ohne das jf ...siehe next...
```

anstelle von [c] Container pane=jf.getContentPane();[/c]
Des weiteren erbt deine Klasse ja von JFrame, was bedeutet gui ist ein JFrame, wieso erstellst du also im Konstruktor noch einen JFrame?


----------



## Michael... (8. Apr 2010)

Zum einen wird in Deinem Code nicht ein Objekt der Klasse gui (KlassenNamen beginnen mit einen Grossbuchstaben) sondern ein interner JFrame (jf) angezeigt.
Zum anderen überschreibt man nicht die paintComponent eines JFrame, sondern man erweitert z.B. die Klasse JComponent oder JPanel und überschreibt deren paintComponent... und fügt ein Objekt dieser Klasse in den JFrame ein.


----------



## André Uhres (8. Apr 2010)

Michael... hat gesagt.:


> Zum anderen überschreibt man nicht die paintComponent eines JFrame


Das geht auch gar nicht, denn ein Hauptfenster (wie JFrame oder JApplet) ist keine JComponent. Ich empfehle erstmal die Lektüre dieser kleinen Einführung: Malen in Swing Teil 1: der grundlegende Mechanismus - Byte-Welt Wiki


----------

