2010-06-25 72 views
0

我使用ActionListener来更新JList,只要选择一个项目。异常似乎杀死JList的更新

jComboBox.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
     JComboBox cb = (JComboBox) e.getSource(); 
     updateLocalFileList(cb.getSelectedItem().toString()); 
    } 
}); 

它正在为UI调用此方法。

public void updateLocalFileList(String path){ 
    DefaultListModel model = new DefaultListModel(); 
    for (String str : LocalFileSystem.getFileListFromDirectory(path)) { 
     model.addElement(str); 
    } 
    getJList().setModel(model); 
} 

如果getFileListFromDirectory()给出了一个NullPointerException,选择一个空的DVD驱动器的盘符时说,这似乎阻止的ActionListener按预期工作。

我不确定究竟发生了什么,但我怀疑向模型传递空值会导致此问题。

任何想法?

编辑

这里是堆栈跟踪的要求。正如你所看到的,该方法显然会触发无法访问的驱动器上的NullPointerException。我不明白为什么它会阻止JList更新,尽管由于其他应用程序工作正常。

java.lang.NullPointerException 
    at mine.View.updateLocalFileList(View.java:274) 
    at mine.View$1.actionPerformed(View.java:262) 
    at javax.swing.JComboBox.fireActionEvent(Unknown Source) 
    at javax.swing.JComboBox.setSelectedItem(Unknown Source) 
    at javax.swing.JComboBox.setSelectedIndex(Unknown Source) 
    at javax.swing.plaf.basic.BasicComboPopup$Handler.mouseReleased(Unknown Source) 
    at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source) 
    at java.awt.Component.processMouseEvent(Unknown Source) 
    at javax.swing.JComponent.processMouseEvent(Unknown Source) 
    at javax.swing.plaf.basic.BasicComboPopup$1.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) 
+0

粘贴stacktrace – OscarRyz 2010-06-25 03:04:39

+1

我知道这并不是你正在发生的事情,但是,看看这个答案,了解如何阅读堆栈跟踪(以及它在第一个地方是什么)http://stackoverflow.com/questions/3066253/java-boxes-mask-not-working/3066299#3066299 – OscarRyz 2010-06-25 03:06:22

+0

@Support是否应该包含链接? – 2010-06-25 03:06:56

回答

2

我会做两件事情,使这更强大。

  1. 确保getFileListFromDirectory永远不会返回null。如果没有项目,则返回Collections.emptyList而不是null。如果不可能,请在使用“for each”迭代之前特别检查返回值。在此情况下,空指针将停止更新模型。 (因此,单击空驱动器将不会清除文件列表。)
  2. 将cb.getSelectedItem()分配给本地变量,并在调用updateLocalFileList之前检查null。如果cb.getSelectedItem()为null,则可以选择清除文件列表。
+0

感谢您的建议。将'Collections.emptyList'添加到方法中是有意义的,因为它应该发回List而不是null引用。我还会在图形方面添加一些检查。 – 2010-06-25 03:20:49

+0

要使getSelectedItem()返回null,请选择一个项目,然后按住CTRL并再次选择该项目。 – 2010-06-25 04:35:49

1

的空指针异常发生在EventDispatchThread(这是所有的GUI更新代码通常发生),所以它中断事件侦听器本身。因此你的GUI不能正确更新(再)。为了防止你必须明确地处理异常,或者拦截导致它们触发的原因。

+0

我有一个扩展'Thread.UncaughtExceptionHandler'的类,我使用'Thread.setDefaultUncaughtExceptionHandler()'在条目中设置它。我不知道这是否足够。目前所做的只是输出文本的例外。 – 2010-06-25 03:18:20

+0

它不是:尝试可视化:getFileListFromDirectory()抛出的异常中断您的事件侦听器; 控制流被传送到你的异常处理程序,所以你的setModel()调用永远不会到达,所以你的GUI没有正确更新。 – user268396 2010-06-25 16:58:36

+0

感谢您的解释。你知道任何网站有一个如何处理Swing应用程序中的异常的好例子吗? – 2010-06-25 18:45:40

1

您的侦听器(引发异常的那个侦听器)并不是唯一一个侦听特定事件的侦听器。 Core Swing类(特别是UI代理)注册了自己的侦听器,以便他们可以正确更新UI。如果您的监听器失败,则无法保证所有(或任何)其他监听器都会收到此特定事件的通知。

0

几个要点:

到底是什么LocalFileSystem类?这是一个自定义类吗?

如果在某些情况下预计它会返回null,那么使用它的局部变量并在调用任何方法之前检查它是否为null。

您可以使用File上的exists方法检查给定的文件或目录是否存在。还有一种isDirectory方法。我建议你考虑使用它。

+0

'LocalFileSystem'确实是一个自定义类。该方法使用File的'list'方法发回一个文件列表(这是为了浏览目录)。它将为空cd/dvd或disquette驱动器返回null。 – 2010-06-25 19:07:21

+0

然后我最好的建议是简单地如下: 每当一个变量可能预期为空*,在调用它的任何方法之前对其进行编程检查。 – Avrom 2010-06-28 17:21:58