# java.lang.NullPointerException



## endidu (25. Mai 2011)

Hallo,

ich bin neu hier im Forum und hoffe das es der richtige bereich ist. also,

Ich arbeite zur Zeit mit grafischer Oberflächen in Java und habe folgendes Problem. Vereinfacht sieht mein Problem so aus:

Ich habe eine grafische Oberfläche mit einem JMenu (JMenuItem: "Neu" und "Beenden") und JButton "Verbinden". Wenn ich main methode aufrufe, soll am Anfang grafische Oberfläche gezeigt werden und "Verbinden" Button soll disabled sein. Bis jetzt funktioniert alles problemlos. und wenn ich JMenuItem "Neu" wähle, sollte "Verbinden" enabled sein. Aber wenn ich drauf klicke, kriege ich folgenden Fehler:


```
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at ToolBar.setStart(ToolBar.java:57)
	at MenuBar.actionPerformed(MenuBar.java:54)
	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at javax.swing.AbstractButton.doClick(Unknown Source)
	at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
	at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
	at java.awt.Component.processMouseEvent(Unknown Source)
	at javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)
```

Wie kann ich diesen Fehler beheben? Ich habe schon gegoogelt und auf einige Sachen gekommen aber die haben mir nicht weiter geholfen. Ich weiss, dass dieses Exception drauf hinweist, dass es um ein NULL Objekt handelt. ich weiss auch, wo der Fehler auftritt, und zwar: ToolBar zTB=new ToolBar(). Ich konnte aber nicht weiterkommen. Ich bin auch kein erfahrener Programmierer. Ich bedanke mich schon einmal im Voraus. Meine Quellcodes:


```
import javax.swing.JFrame;
import javax.swing.JPanel;

import org.jfree.ui.RefineryUtilities;

import com.jgoodies.forms.factories.CC;
import com.jgoodies.forms.layout.FormLayout;

public class MainFrame extends JFrame {

	JPanel hauptPanel;
	public static MenuBar Menu;
	public ToolBar ToolBar;

	public MainFrame() {

		Menu = new MenuBar(this);
		ToolBar = new ToolBar("");
		hauptPanel = new JPanel();
		setLayout(new FormLayout("pref:grow", "pref,pref"));
		setTitle("TEST");
		makeFrame();
		setFocusable(true);
		pack();
		RefineryUtilities.centerFrameOnScreen(this);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setVisible(true);
	}

	private void makeFrame() {
		setJMenuBar(Menu);
		add(ToolBar, CC.xy(1, 1));
		add(hauptPanel, CC.xy(1, 2));
		FormLayout layout = new FormLayout("pref:grow", "pref");
		hauptPanel.setLayout(layout);

	}
```


```
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

public  class MenuBar extends JMenuBar implements ActionListener{
	

	private JMenu		menuDatei;

	private JMenuItem	itemNeu,
						itemBeenden;
	
	public MainFrame mainFrame;
		
	public String 	selectedPort = null;
	
	public MenuBar(MainFrame frame){
		mainFrame = frame;
		makeMenuDatei();		
	}
	
	private void makeMenuDatei(){
		menuDatei		= new JMenu("Datei");
		
		itemNeu			= new JMenuItem("Neu");
		itemBeenden		= new JMenuItem("Beenden");
		
		itemNeu.addActionListener(this);
		itemBeenden.addActionListener(this);
		
		menuDatei.add(itemNeu);
		menuDatei.addSeparator();
		menuDatei.add(itemBeenden);
		
		add(menuDatei);
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		Object ae = e.getSource();
			if ( ae == itemBeenden) {
				try {
					
				} catch (Exception e1) {
					e1.printStackTrace();
				}
				System.exit(0);
			}
			else if (ae == itemNeu) {
				ToolBar zTB=new ToolBar();
				zTB.setStart(true);
			}
		}
}
```


```
import javax.swing.JButton;
import javax.swing.JToolBar;

public class ToolBar 	extends 	JToolBar {

	final static public String CONNECT_COMMAND			= "Verbinden";
	final static public String DISCONNECT_COMMAND		= "Trennen";
	
	public JButton 		startStop;
	
	public ToolBar(){
		
	}
	
	public ToolBar(String str) {
		addButtons();
		setFloatable(false);
	}

	protected void addButtons(){
		startStop = makeNavigationButton(CONNECT_COMMAND);
		setStart(false);
		add(startStop);
	}
	
	protected JButton makeNavigationButton(String actionCommand){
		JButton button = new JButton();
		button.setActionCommand(actionCommand);
		button.setToolTipText(actionCommand);
		button.addActionListener(new ToolbarListner());
		button.setText(actionCommand);
		return button;
	}

	public void setDisconnectedState(JButton button) {

		button.setActionCommand(ToolBar.CONNECT_COMMAND);
		button.setText(ToolBar.CONNECT_COMMAND); 
		button.setToolTipText(ToolBar.CONNECT_COMMAND);

	}
	
	public void setConnectedState(JButton button) {
		button.setActionCommand(ToolBar.DISCONNECT_COMMAND);
		button.setText(ToolBar.DISCONNECT_COMMAND); 
		button.setToolTipText(ToolBar.DISCONNECT_COMMAND);
	}

	public void setStart(boolean bool){
		startStop.setEnabled(bool);
	}

}
```


```
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;

public class ToolbarListner implements ActionListener{

	ToolBar zTB= new ToolBar();

	@Override
	public void actionPerformed(ActionEvent e) {

		if(e.getActionCommand().equals(ToolBar.CONNECT_COMMAND)){
			connectClick(e.getSource());
		}
	}

	private void connectClick(Object object){
		JButton buttonConnect = (JButton)object;
		zTB.setConnectedState(buttonConnect);
	}
	
}
```


----------



## Fu3L (25. Mai 2011)

Klasse MenuBar Zeile 53 

Da rufst du den Konstruktor ohne Parameter auf, der keinen Button erzeugt.


----------



## endidu (25. Mai 2011)

Danke für die sehr schnelle Antwort. Aber mit welchem Parameter soll ich den Konstruktor aufrufen. Ich habe mit string versucht. aber klappt irgendwie nicht. ???:L


----------



## Miness (25. Mai 2011)

Nun, der Konstruktor mit dem String als Parameter macht ja wenig Sinn, nicht? Du verarbeitest diesen String ja gar nicht ...

Schreibe den No-Arg-Konstruktor der Klasse ToolBar einfach mal so um:


```
public ToolBar() {
    addButtons();
    setFloatable(false);  
}
```
 
Danach kannst du den Konstruktor mit dem String als Parameter theoretisch löschen. Natürlich musst du dann noch alle Aufrufe dieses Konstruktors bereinigen (beispielsweise in "MainFrame").


----------



## Andi_CH (25. Mai 2011)

Zeile 13 im Mainframe

```
public ToolBar ToolBar;
```
wird ja so wohl auch kaum funktionieren.

Variablennamen sollen klein geschrieben werden und um die Lesbarkeit zu verbessern sollte es auch nicht zwingend

```
public ToolBar toolBar;
```
heissen (Nein ich schreibe meine favorisierte Varaiante nicht hin, sonst werde ich wieder gelyncht)
auf jeden Fall sollte es eine Bezeichnung sein, die aussagt was dahinter steckt.


```
public ToolBar meinToolBar;
```

ist ein Vorschlag, wenn auch nicht der Beste.


----------



## endidu (25. Mai 2011)

Miness hat gesagt.:


> Nun, der Konstruktor mit dem String als Parameter macht ja wenig Sinn, nicht? Du verarbeitest diesen String ja gar nicht ...
> 
> Schreibe den No-Arg-Konstruktor der Klasse ToolBar einfach mal so um:
> 
> ...



Erstmal Danke. Ich benutze eigentlich den Konstruktor mit dem String in meinem eigenem Programm, um Port-Name mitzugeben. Ich habe hier aber die ganze Quelcodes nicht mitgeschickt, habe die Quellcodes gelöscht, die ich hier jetzt nicht brauche, um mein Problem zu veranschaulichen. Deswegen sieht es hier so unsinnig aus.

Außerdem, wenn ich auch mit dem obigen Konstruktor aufrufe, geht es immer noch nicht. Ich habe auch so probiert:
den Konstruktor mit dem 

```
setStart(str);
```
ergänzt. Und die habe ich in mainFrame mit 

```
toolBar = new ToolBar("Trennen");
```
und in MenuBar mit

```
else if (ae == itemNeu) {
       new ToolBar("Verbinden");
       }
```
aufgerufen. Und die Methode setStart(String str) sieht jetzt so aus:

```
public void setStart(String str){
		if (str=="Verbinden"){
			startStop.setEnabled(true);
			System.out.println("HIER"); //Um zu sehen, ob es hier gelandet wird.
		}
		if (str=="Trennen")
			startStop.setEnabled(false);
	}
```
Dieses Mal kriege ich nicht mehr Exception aber wird der Button "Verbinden" immer noch nicht enabled. 
Hilfe bitte???:L

PS: Und Andi, du hast Recht. Ich habe es jetzt kleingeschrieben.


----------



## Fu3L (25. Mai 2011)

> Dieses Mal kriege ich nicht mehr Exception aber wird der Button "Verbinden" immer noch nicht enabled.
> 
> ```
> if (str=="Verbinden"){
> ...



Wäre interessant zu wissen, ob die Ausgabe auch passiert, dann kann man den Fehler schon leichter eingrenzen  (is noch zu früh am Morgen D), um alles noch einmal zu lesen^^)


----------



## endidu (25. Mai 2011)

Wenn ich in der Klasse "ToolBar" den JButton "startStop" als static definiere

```
public static JButton 		startStop;
```
und in der Klasse "MenuBar" 

```
else if (ae == itemNeu) {
	//new ToolBar("Verbinden");
	ToolBar.startStop.setEnabled(true);
}
```
 wird mein Problem gelöst.

Aber ich glaube, das ist keine gute Programmierung, oder? Was meint ihr dazu???:L Danke im Voraus.


----------



## endidu (25. Mai 2011)

Fu3L hat gesagt.:


> Wäre interessant zu wissen, ob die Ausgabe auch passiert, dann kann man den Fehler schon leichter eingrenzen  (is noch zu früh am Morgen D), um alles noch einmal zu lesen^^)



Ja, "HIER" wird ausgegeben, wenn ich auf den MenuItem "Neu" klicke.


----------



## Fu3L (25. Mai 2011)

Es sollte auch funktionieren ohne das static zu machen... Könnte es sein, dass du die neue ToolBar einfach erstellst, aber gar nicht die alte damit ersetzt?
Der static-Button existiert nur einmal, in jeder Instanz von ToolBar. Änderst du diesen, ändert er sich auch in der alten Instanz von der JToolBar^^ 
Wenn das etwas ist, womit du zufrieden wärest, würde ich das aber trotzdem irgendwie so umbauen, dass du setStart() auf einer Instanz von ToolBar aufrufst^^


----------



## endidu (25. Mai 2011)

ich will auch  nicht, dieses Problem mit static zu lösen. Es sollte eine andere Lösung existieren. Aber mit dem Konstruktoren und Instanzen habe ich viel versucht. Geht irgendwie nicht. 


> Könnte es sein, dass du die neue ToolBar einfach erstellst, aber gar nicht die alte damit ersetzt?



ja, es kann sein. Aber wie soll ich dann die alte ersetzen? habe mit parameter versucht, aber klappt nicht. Der neue Button wird immer Null. Ich würde mich sehr freuen, wenn du als Quelcode schreiben könntest.


----------



## Fu3L (25. Mai 2011)

In MenuBar beim Eventhandling schreibst du:

mainFrame.changeButtonState("Hier Text");

Dann definierst du eine Methode in MainFrame:


```
public void changeButtonText(String s) {
   toolBar.startStop.setText(s);
}
```

Ähnliches kannst du natürlich dann auch mit setEnabled und so machen^^ Musst halt nochn Parameter mehr übergeben oder in changeButtonText anhand des Textes entscheiden.. Je nach dem^^

Edit: Vllt wäre es schönerer Programmierstil den start-stop button zu verbergen und in ToolBar noch eine Methode hinzuzufügen, die die Textänderung dann erst vornimmt^^


----------



## endidu (25. Mai 2011)

vielen vielen Dank. so wurde das Problem gelöst.:toll:: Ich werde jetzt die Methoden so erweitern, indem ich jeweilige Buttons auch als Parameter eingeben kann, usw.. Danke nochmal..
Bevor ich aber das Thema als erledigt markiere, möchte ich noch was fragen. Wieso hat es nicht funktioniert, wie ich in der Fragestellung geschrieben habe und wieso läuft es jetzt problemlos, wenn wir die Methoden in MainFrame schreiben. Ich möchte gerne auch den Sinn darunter verstehen.


----------



## Fu3L (25. Mai 2011)

Du hast eine neue Instanz der Klasse ToolBar erzeugt. Eine Instanz weiß so einfach nichts über andere Instanzen der Klasse, außer es gibt statische Variablen in dieser Klasse. Diese gelten für JEDE Instanz dieser Klasse. 
Du musst also entweder von MenuBar aus der Instanz von MainFrame mitteilen, dass etwas mit der Instanz der ToolBar passieren soll, die du in MainFrame angelegt hast, so wie ich das zuvor auch beschrieb. Die andere Möglichkeit wäre, in MenuBar irgendwie an die Instanz von ToolBar zu kommen, die MainFrame zuvor angelegt hat (auch über ne Getter-Methode oder als Parameter beim Erzeugen der Instanz von MenuBar). Wobei erstes wohl schöner ist (siehe in den FAQ nach dem oft beschworenen MVC Pattern, wo es eine kontrollierende Klasse gibt^^)

Ich hoffe, das kann man verstehen^^ Ansonsten einfach noch einmal fragen


----------



## endidu (25. Mai 2011)

Danke nochmal, ich habe es jetzt verstanden. Da ich mich noch weiter mit grafischen Oberflächen beschäftigen werde, werde ich versuchen, MVC Pattern ausführlich zu lernen/ zu verstehen.
Ich markiere somit das Thema als erledigt.


----------

