# NullPointerException bei Aufruf von updateUI() beim JFrame



## stebr (15. Sep 2008)

Hallo!

Bei meinem Programm benutze ich eine JList in einem JFrame um Textnachrichten auszugeben. Dabei erhalte ich mehrere NullPointerExceptions (siehe unten). Die Ausgabe aktualisiere ich mit folgender Methode.


```
public void addLine(String _message)
	{
		messages.add(_message);
		list.updateUI();		
	}
```

Ich vermute, dass der Fehler beim Aufruf von updateUI() auftritt. 

Sehr komisch dabei finde ich, dass wenn ich das Programm im Debugmodus starte und ich einen Breakpoint vor dem updateUI() Aufruf mache, dass dann keine Exception entsteht. Ich habe daraufhin mal den updateUI() Aufruf versuchsweise weggelassen und nur noch ganz am Ende einmal updateUI() Aufgerufen. Auch dabei erhielt ich keine NPException mehr (zumindest nicht so viele).

Ich bin ziemlich ratlos und dankbar für eure Hilfe!

Viele Grüße, Stephan



Hier die ausgeworfenen Exceptions:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at javax.swing.plaf.basic.BasicListUI.getHeight(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.paintImpl(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
	at javax.swing.plaf.ComponentUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintToOffscreen(Unknown Source)
	at javax.swing.BufferStrategyPaintManager.paint(Unknown Source)
	at javax.swing.RepaintManager.paint(Unknown Source)
	at javax.swing.JComponent._paintImmediately(Unknown Source)
	at javax.swing.JComponent.paintImmediately(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
	at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(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)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at javax.swing.plaf.basic.BasicListUI.updateLayoutState(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.paintImpl(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
	at javax.swing.plaf.ComponentUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintToOffscreen(Unknown Source)
	at javax.swing.BufferStrategyPaintManager.paint(Unknown Source)
	at javax.swing.RepaintManager.paint(Unknown Source)
	at javax.swing.JComponent._paintImmediately(Unknown Source)
	at javax.swing.JComponent.paintImmediately(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
	at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(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)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at javax.swing.plaf.basic.BasicListUI.updateLayoutState(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.paintImpl(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
	at javax.swing.plaf.ComponentUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintToOffscreen(Unknown Source)
	at javax.swing.BufferStrategyPaintManager.paint(Unknown Source)
	at javax.swing.RepaintManager.paint(Unknown Source)
	at javax.swing.JComponent._paintImmediately(Unknown Source)
	at javax.swing.JComponent.paintImmediately(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
	at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(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)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at javax.swing.plaf.basic.BasicListUI.updateLayoutState(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.paintImpl(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
	at javax.swing.plaf.ComponentUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintToOffscreen(Unknown Source)
	at javax.swing.BufferStrategyPaintManager.paint(Unknown Source)
	at javax.swing.RepaintManager.paint(Unknown Source)
	at javax.swing.JComponent._paintImmediately(Unknown Source)
	at javax.swing.JComponent.paintImmediately(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
	at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(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)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at javax.swing.plaf.basic.BasicListUI.updateLayoutState(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.paintImpl(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
	at javax.swing.plaf.ComponentUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintToOffscreen(Unknown Source)
	at javax.swing.BufferStrategyPaintManager.paint(Unknown Source)
	at javax.swing.RepaintManager.paint(Unknown Source)
	at javax.swing.JComponent._paintImmediately(Unknown Source)
	at javax.swing.JComponent.paintImmediately(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
	at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(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)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at javax.swing.plaf.basic.BasicListUI.updateLayoutState(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.paintImpl(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
	at javax.swing.plaf.ComponentUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintToOffscreen(Unknown Source)
	at javax.swing.BufferStrategyPaintManager.paint(Unknown Source)
	at javax.swing.RepaintManager.paint(Unknown Source)
	at javax.swing.JComponent._paintImmediately(Unknown Source)
	at javax.swing.JComponent.paintImmediately(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
	at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(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)
	
	
	
	





```

```


----------



## Marco13 (15. Sep 2008)

Ruf' updateUI einfach nicht auf.

(Und bevor du jetzt eine wütende Antwort schreibst, in der das Wort "veräppelt" vorkommt, lies' dir die Doku zu updateUI mal durch)


----------



## stebr (15. Sep 2008)

Habe den Aufruf von updateUI() auf der JList durch einen Aufruf von repaint() auf dem JFrame ersetzt. Jetzt kommt auch keine Exception mehr -> das ist schon mal gut!!! Aber leider werden jetzt die Nachrichten nicht mehr angezeigt. Man sieht also nur einen leeren JFrame -> das ist leider schlecht!!!

Wie kann ich denn jetzt dieses Problem beheben? Und wieso funktionierte das mit updateUI() nicht? Ich verstehe jetzt zwar, dass dies eine ungeeignete Funktion für mein Vorhaben war, aber die ruft im Grunde doch auch repaint() auf den einzelnen Komponenten auf, oder nicht?

Gruß, Stepha


----------



## GilbertGrape (15. Sep 2008)

Ich denke, du musst deine addLine Methode in einen separaten Thread auslagern, weil der Event Dispatch Thread nur damit beschäftigt ist und "keine Zeit" für seine eigentlich Aufgabe, das Zeichnen der GUI hat.
SwingWorker ist hilfreich!

Gruß,
GG


----------



## Marco13 (15. Sep 2008)

Bevor du da jetzt mit nem SwingWorker drauf einprügelst, solltest du genauer beschreiben, WO und WANN du diese Methode auffrufst.

BWT:
frame.setVisible(true);
sollte erst gemacht werden, wenn alles fertig ist - damit KÖNNTE es zusammenhängen.


----------



## stebr (15. Sep 2008)

Hallo und danke für eure Hilfe!

Bei dem JFrame handelt es sich einfach gesagt um ein Ausgabefenster, indem zur Laufzeit bestimmte Ausgaben protokolliert werden sollen, damit dem Benutzer diese Ausgaben zur Laufzeit zur Verfügung stehen. Deswegen wäre es nicht angebracht erst am Ende alle Daten gleichzeitig auszugeben. Es entszehen zur Laufzeit also ständig neue Ausgaben, die sofort dargestellt werden sollen. In diesem Moment rufe ich die oben stehende Methode addLine() auf. In dieser Methode wird der JList eine neue Ausgabe hinzugefügt. Anschließend soll sich das JFrame aktualisieren, um die neue Ausgabe anzuzeigen.

Gruss, Stephan


----------



## GilbertGrape (15. Sep 2008)

also doch n SwingWorker


----------



## Marco13 (15. Sep 2008)

Nicht unbedingt. Was heißt "aktualisieren"? Man sollte nur im Event-Dispatch-Thread Elemente zur JList hinzufügen. Und das passiert nicht mit einem SwingWorker, sondern mit SwingUtilities (sofern der andere Thread nicht ein SwingWorker ist :roll: ). Je nachdem, was du mit "aktualisieren" meintest, kannst du statt des updateUI() mal 
validate();
repaint();
schreiben.


----------



## stebr (15. Sep 2008)

Leider brachte das auch noch nichts. Ich kann mir auch nicht vorstellen, dass ich zur Lösung dieses Problems ein Swingworker brauche- zumindest verstehe ich nicht warum ich den brauchen könnte.

Ich poste jetzt mal die gesamte Klasse des JFrames, inder sich auch die addLine() Methode befindet. Vieleicht hat dann jemand ja noch ne Idee. (Nur zur Erinerung: Die Execptions treten nicht mehr auf, seitdem ich das updateUI() weglasse. Nur der JFrame bleibt leer und gibt nichts aus.)


```
public class AgentFrontEndGUI extends JFrame {
	
	private Vector<String> messages;
	private JList list;
	
	/**
	 * @throws HeadlessException
	 */
	public AgentFrontEndGUI(String _agentName) throws HeadlessException {
		super(_agentName);
		//this.setSize(800,600);
		messages = new Vector<String>();
		list = new JList(messages);
		list.setVisibleRowCount(50);
		
		JScrollPane listPane = new JScrollPane(list);
	    
	    JPanel listPanel = new JPanel();
	    //list.setSize(600,420);
	    listPanel.setBackground(Color.white);
	    Border listPanelBorder =
	    BorderFactory.createTitledBorder("Agent Output:");
	    listPanel.setBorder(listPanelBorder);
	    listPanel.add(listPane);
		this.getContentPane().add(listPanel);
		pack();
		setVisible(true);
	}
	
	public void addLine(String _message)
	{
		messages.add(_message);
		//this.validate();
		list.repaint();	//Hier müsste der AWT-Error herkommen	
	}
}
```


----------



## kleiner_held (15. Sep 2008)

Eine JList mit einem Vector zu initialisieren und dann den Vector quasi heimlich immer zu erweitern ist nicht gut, die JList bekommt davon naemlich ueberhaupt nix mit (keine ListDataEvent's).

```
DefaultListModel model = new DefaultListModel();
JList list = new JList(messages); 
// und dann immer 
model.addElement("dein String");
```


----------



## stebr (15. Sep 2008)

Wenn ich das richtig verstehe soll ich also ein DefaultListModel Objekt model erzeugen. Muss ich dann anschließend meine JList mit messages oder mit model instanziieren? Bei dir steht es in Zeile 2 ja mit messages, aber wenn ich das DefaultListModel Objekt anlege habe ich doch gar keinen Vector messages mehr, oder? Daher habe ich meine JList jetzt mit dem DefaultListModel instanziiert - bei mir heißt dieses Model jetzt aber messages. Den Vector habe ich rausgeworfen. Mein Code sieht jetzt folgendermaßen aus... Jetzt funktioniert es auch allerdings, nicht immer. Manchmal bleibt der Frame wieder leer...???


```
public class AgentFrontEndGUI extends JFrame {
	
	DefaultListModel messages = new DefaultListModel();  //***habe dies hinzugefügt und den Vector weggelassen***
	private JList list;
	
	/**
	 * @throws HeadlessException
	 */
	public AgentFrontEndGUI(String _agentName) throws HeadlessException {
		super(_agentName);
		//this.setSize(800,600);
		list = new JList(messages);
		list.setVisibleRowCount(50);
		
		JScrollPane listPane = new JScrollPane(list);
	    
	    JPanel listPanel = new JPanel();
	    //list.setSize(600,420);
	    listPanel.setBackground(Color.white);
	    Border listPanelBorder =
	    BorderFactory.createTitledBorder("Agent Output:");
	    listPanel.setBorder(listPanelBorder);
	    listPanel.add(listPane);
		this.getContentPane().add(listPanel);
		pack();
		setVisible(true);
	}
	
	public void addLine(String _message)
	{
		messages.addElement(_message);
		list.repaint();	
	}
}
```


----------



## kleiner_held (16. Sep 2008)

Ja das mit model/messages war (wie ueblich) ein Copy-Paste Fehler, die JList soll mit dem DefaultListModel initialisiert werden.

Ich habe deinen Code mal um eine main Methode erweitert, in der ein Fenster erstellt und kontinuierlich mit Nachrichten gefuettert wird.
Wie man sieht ist ein repaint() gar nicht noetig, DefaultListModel.addElement() reicht voellig aus.
Da die Nachrichten nicht im AWTEventThread generiert werden, ist es notwendig das updaten mittels SwingUtilities.invokeLater() auszufuehren, das wars auch schon.

PS: wenn es die um die Anzeige von Log-Messages geht wuerde ich anstatt einer JList eher eine (nicht editierbare) JTextArea empfehlen. Das Prinzip ist das gleiche, nur dass du halt JTextArea.append(String) anstatt von DefaultListModel.addElement(Object) verwendest. Das ist aber halt nur Geschmackssache.


```
public class AgentFrontEndGUI extends JFrame
{
	DefaultListModel messages = new DefaultListModel(); 
	private JList list;

	/**
	 * @throws HeadlessException
	 */
	public AgentFrontEndGUI(String _agentName) throws HeadlessException {
		super(_agentName);
		// this.setSize(800,600);
		list = new JList(messages);
		list.setVisibleRowCount(50);

		JScrollPane listPane = new JScrollPane(list);

		JPanel listPanel = new JPanel(new BorderLayout());
		// list.setSize(600,420);
		listPanel.setBackground(Color.white);
		Border listPanelBorder = BorderFactory
				.createTitledBorder("Agent Output:");
		listPanel.setBorder(listPanelBorder);
		listPanel.add(listPane);
		this.getContentPane().add(listPanel);
		pack();
		setVisible(true);
	}

	public void addLine(String _message) {
		messages.addElement(_message);
	} 
	   
	public static void main(String[] args) {
		final AgentFrontEndGUI frame = new AgentFrontEndGUI("Agent");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		class Counter implements Runnable {
			int cnt = 0;
			
			public void run() {
				frame.addLine("line " + cnt++);
			}
		}
		Counter counter = new Counter();
		while (true) {
			try {
				Thread.sleep(1000);
				SwingUtilities.invokeLater(counter);
			}
			catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
```


----------



## stebr (19. Sep 2008)

Danke für eure Hilfe! Es funktioniert jetzt alles wie gewünscht. 

@kleiner_Held: Der Tipp mit invokeLater() hat das gewünschte Ergebnis gebracht. Das Fenster wird jetzt immer korrekt angezeigt. Danke!

Viele Grüße, Stephan


----------

