Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception on deleting JList items on keypress

Tags:

java

swing

jlist

I'm getting a NullPointerException in my JList, but the source of the exception seems to be the Swing event handling code. The JList has a key listener which will delete the selected item when the Delete key is pressed. The exception is only thrown on the second and all subsequent deletions from the list. Any ideas on how to fix it?

Sample code to reproduce the problem and the exception that is produced are included 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 being thrown:

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)
like image 675
David S. Avatar asked Dec 28 '22 17:12

David S.


2 Answers

The problem is in this line:

 listView.updateUI();

Calling this method causes the current UI to be uninstalled from the JList, yet it is still being used to process events. This results in the NullPointerException you see. This isn't the method you want to call.

Try

 listView.revalidate();

instead to cause the component to re-layout or perhaps just repaint() to get it to repaint.

like image 192
Mark Peters Avatar answered Jan 08 '23 10:01

Mark Peters


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

EDIT: remove unrelated code

like image 38
mKorbel Avatar answered Jan 08 '23 12:01

mKorbel