Exception when deleting JList items when a key is pressed

I get a NullPointerException in my JList, but the exception source is Swing event handling code. JList has a keyboard listener that deletes the selected item when the Delete key is pressed. The only exception is the second and all subsequent deletions from the list. Any ideas on how to fix this?

Sample code to reproduce the problem and throw an exception is shown below:

import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.Vector; import javax.swing.JFrame; import javax.swing.JList; public class Sample { public static void main(String[] args) { final JFrame frame = new JFrame(); final Vector<String> list = new Vector<String>(); for (int i = 0; i < 5; ++i) { list.add("String " + i); } final JList listView = new JList(list); listView.addKeyListener(new KeyListener() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_DELETE) { list.remove(listView.getSelectedIndex()); listView.updateUI(); } } @Override public void keyReleased(KeyEvent e) { } @Override public void keyTyped(KeyEvent e) { } }); frame.add(listView); frame.pack(); frame.setVisible(true); } } 

Here's the exception:

 Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at javax.swing.plaf.basic.BasicListUI$Handler.isNavigationKey(Unknown Source) at javax.swing.plaf.basic.BasicListUI$Handler.keyPressed(Unknown Source) at java.awt.AWTEventMulticaster.keyPressed(Unknown Source) at java.awt.Component.processKeyEvent(Unknown Source) at javax.swing.JComponent.processKeyEvent(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.KeyboardFocusManager.redispatchEvent(Unknown Source) at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(Unknown Source) at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source) at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source) at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source) at java.awt.Component.dispatchEventImpl(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.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access$000(Unknown Source) at java.awt.EventQueue$1.run(Unknown Source) at java.awt.EventQueue$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source) at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue$2.run(Unknown Source) at java.awt.EventQueue$2.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(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) 
+4
source share
3 answers

The problem is in this line:

  listView.updateUI(); 

Calling this method removes the current UI from the JList , but it is still used to handle events. The result is a NullPointerException . This is not the method you want to call.

Try

  listView.revalidate(); 

instead, to force the component to reformat, or perhaps just repaint() to redraw it.

+5
source
 list.registerKeyboardAction(this, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), JComponent.WHEN_FOCUSED); 

EDIT: delete unrelated code

+2
source

Instead of updateUI (), you should call the revalidate () and repaint () methods. And probably checking if the item really exists in the list would not be a bad idea.

  @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_A) { if(list.get(listView.getSelectedIndex()) != null) { list.remove(listView.getSelectedIndex()); listView.revalidate(); listView.repaint(); } } } 
+2
source

All Articles