【问题标题】:Exception seems to kill updating of a JList异常似乎终止了 JList 的更新
【发布时间】:2010-06-25 02:57:49
【问题描述】:

I'm using an ActionListener to update a JList whenever an item is selected.

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)

【问题讨论】:

标签: java swing exception jcombobox


【解决方案1】:

我会做两件事来使它更健壮。

  1. 确保 getFileListFromDirectory 永远不会返回 null。如果没有项目,则返回 Collections.emptyList 而不是 null。如果这不可能,请在使用“for each”迭代之前专门检查返回值。实际上,空指针将阻止模型更新。 (因此单击空驱动器不会清除文件列表。)
  2. 将 cb.getSelectedItem() 分配给局部变量并在调用 updateLocalFileList 之前检查是否为空。如果 cb.getSelectedItem() 为 null,您可以选择清除文件列表。

【讨论】:

  • 感谢您的建议。将Collections.emptyList 添加到该方法是有意义的,因为它应该发回一个List 而不是一个空引用。我还将在图形方面添加一些检查。
  • 要使 getSelectedItem() 返回 null,请选择一个项目,然后按住 CTRL 并再次选择该项目。
【解决方案2】:

NullPointerException 发生在 EventDispatchThread(这是所有 GUI 更新代码通常发生的地方),因此它会中断事件侦听器本身。因此,您的 GUI 无法正确更新(不再)。为防止这种情况发生,您必须显式处理异常,或拦截可能触发它们的原因。

【讨论】:

  • 我有一个扩展 Thread.UncaughtExceptionHandler 的类,我使用 Thread.setDefaultUncaughtExceptionHandler() 在条目中设置它。我不知道这是否足够。目前它所做的只是向文本输出一个异常。
  • 不是:试着想象一下:getFileListFromDirectory() 抛出的异常会中断你的事件监听器;控制流被转移到您的异常处理程序,因此您的 setModel() 调用永远不会到达,因此您的 GUI 没有正确更新。
  • 感谢您的解释。你知道有哪些网站有很好的例子来说明如何在 Swing 应用程序中处理异常吗?
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    几点:

    LocalFileSystem 类到底是什么?那是自定义类吗?

    如果在某些情况下预期它会返回 null,则为其使用一个局部变量并在调用任何方法之前检查它是否为 null。

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

    【讨论】:

    • LocalFileSystem 确实是一个自定义类。该方法使用 File 的 list 方法发送回文件列表(这是用于在目录中导航)。对于空的 cd/dvd 或磁盘驱动器,它将返回 null。
    • 那么我最好的建议就是以下几点:每当变量中可能为空时,在调用任何方法之前对其进行编程检查。
    猜你喜欢
    • 2011-07-30
    • 2019-09-30
    • 1970-01-01
    • 2016-07-13
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-18
    相关资源
    最近更新 更多