2013-08-20 193 views
3

當我運行(在運行或調試模式下)我的項目,我得到一個ArrayIndexOutOfBounds錯誤,這是有道理的。什麼不是,我檢查是否索引> = 0,儘管它說索引是-1,不知何故if內的代碼仍然運行。如果語句執行失敗

代碼:

... 
// Contact List 
lstContacts = new JList(); 
lstContacts.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
lstContacts.setPreferredSize(new Dimension(200, 200)); 
lstContacts.setMinimumSize(new Dimension(50, 50)); 
_contactList = _dbi.GetContactList(); 
_selectedIndex = -1; // An int declared earlier 
lstContacts.setListData(_contactList.toArray()); 
lstContacts.addListSelectionListener(new ListSelectionListener() 
{ 
    public void valueChanged(ListSelectionEvent e) 
    { 

     System.out.println(); 
     System.out.println("lstContacts.getSelectedIndex: " + lstContacts.getSelectedIndex()); 
     System.out.println("!e.getValueIsAdjusting: " + (!e.getValueIsAdjusting())); 
     System.out.println("getselectedindex > 0: " + (lstContacts.getSelectedIndex() > 0)); 
     System.out.println("Both: " + (!e.getValueIsAdjusting() && (lstContacts.getSelectedIndex() > 0))); 

     // Filter out mid-actions 
     if(!e.getValueIsAdjusting() && (lstContacts.getSelectedIndex() > 0)) 
     { 

      if(pnlDetail.isVisible()) 
      { 
       saveCurrentContact(); 
      } 
      else 
      { 
       pnlDetail.setVisible(true); 
      } 

      System.out.println(" Both: " + (!e.getValueIsAdjusting() && (lstContacts.getSelectedIndex() > 0))); 
      _selectedIndex = lstContacts.getSelectedIndex(); 
      System.out.println(" _selectedIndex: " + _selectedIndex); 
      System.out.println(" lstContacts.getSelectedIndex: " + lstContacts.getSelectedIndex()); 
      PersonalContact sc = (PersonalContact)_contactList.get(_selectedIndex); //crashes here 
      showContact(sc); 
     } 
    } 
}); 
... 

我插入列表中的三個虛擬接觸開始。點擊一個運行正常,但點擊另一個會拋出錯誤。在下面的錯誤中,我點擊了第二個條目。

控制檯輸出:

... 
lstContacts.getSelectedIndex: 2 
!e.getValueIsAdjusting: true 
getselectedindex > 0: true 
Both: true 
Entry ID [2] modified. 

lstContacts.getSelectedIndex: -1 
!e.getValueIsAdjusting: true 
getselectedindex > 0: false 
Both: false 
    Both: false 
    _selectedIndex: -1 
    lstContacts.getSelectedIndex: -1 
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1 
    at java.util.ArrayList.elementData(Unknown Source) 
    at java.util.ArrayList.get(Unknown Source) 
    at main.ContactPanel$2.valueChanged(ContactPanel.java:203) 
    at javax.swing.JList.fireSelectionValueChanged(Unknown Source) 
    at javax.swing.JList$ListSelectionHandler.valueChanged(Unknown Source) 
     ... [continued] 

它看起來像它運行正常,然後再次運行和崩潰。我錯過了什麼(可能是顯而易見的東西)?感謝您的時間和您可以提供的任何幫助。

+0

這是在多個線程中運行? 如果條件爲真,那麼一旦您在if語句中索引被修改,這可能是原因。 –

+0

@Moonfile - 看起來有多個線程在同一個對象上工作,這可能會導致此問題。 –

+0

爲了儘快提供更好的幫助,請發佈[SSCCE](http://sscce.org/)。 –

回答

2

正如註釋到您的文章指出,很可能是一些其他線程正在更新您的列表,並通過你JList.getSelectedIndex檢查其值()時不選擇一切。你沒有顯示你的所有代碼,但是你可能在稍後使用lstContacts做一些事情,那就是清除列表中的所有選擇。

由於您想要響應特定事件,因此不要檢查列表中選定的值,在多線程環境中,這些值可能會從一個瞬間變化到另一個瞬間。相反,請檢查ListSelectionEvent.getFirstIndex())事件選擇的值,該值對於該事件應該是不變的。

您可能會發現Oracle的Concurrency In Swing教程很有幫助。

+0

Liiightbulb。你給的鏈接只是提醒我使用.invokeLater()在整個程序中的main()。想想我以前記得e.getFirstIndex()給我帶來麻煩,但我們會看到。非常感謝你! – Melde

4

這是很清楚的:

兩種:假
兩種:假
_selectedIndex:-1
lstContacts.getSelectedIndex:-1
異常在線程 「AWT-EventQueue的-0的」 java .lang.ArrayIndexOutOfBoundsException:-1

所選索引爲-1相同操作的方式:

_contactList.get(-1); 

記住,幾乎所有的Java集合需要索引> = 0

我想,如果用戶有(或沒有)選擇列表中的項目,所以你應該修改你的病情,以便檢查可以處理錯誤。例如:

if(lstContacts.getSelectedIndex() >= 0){ 
    _selectedIndex = lstContacts.getSelectedIndex(); 
    PersonalContact sc = (PersonalContact)_contactList.get(_selectedIndex); 
    showContact(sc); 
} 

希望它有幫助。

快樂編碼!

EFRA

+1

我很感激你花時間指出,但這不是我所關心的部分。它試圖訪問-1索引崩潰是有道理的。但是,在上面我檢查索引是否大於等於0,但它仍然運行。 – Melde

+0

@mKorbel這是正確的我正在編輯。 – Omar