按键时删除 JList 项目的异常
我在 JList 中收到 NullPointerException,但异常的来源似乎是 Swing 事件处理代码。 JList 有一个按键侦听器,按下删除键时将删除所选项目。仅当从列表中进行第二次删除和所有后续删除时才会引发异常。关于如何修复它有什么想法吗?
下面包含重现问题和生成的异常的示例代码:
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);
}
}
这是抛出的异常:
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)
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题出在这一行:
调用此方法会导致当前 UI 从
JList
中卸载,但仍用于处理事件。这会导致您看到的NullPointerException
。这不是您想要调用的方法。尝试
让组件重新布局,或者只是通过
repaint()
来重新绘制。The problem is in this line:
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 theNullPointerException
you see. This isn't the method you want to call.Try
instead to cause the component to re-layout or perhaps just
repaint()
to get it to repaint.编辑:删除不相关的代码
EDIT: remove unrelated code
您应该调用 revalidate() 和 repaint() 方法,而不是 updateUI()。检查列表中的元素是否确实存在可能不是一个坏主意。
Instead of the updateUI() you should call the revalidate() and repaint() method. And probably a check if the element in the list really exists wouldn't be a bad idea.