2010-06-25 43 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