简体   繁体   中英

If Statement Executing When False

When running (in run or debug mode) my project, I get an ArrayIndexOutOfBounds error, which makes sense. What doesn't is that I check if the index >= 0, and despite it saying the index is -1, somehow the code inside the if still runs.

Code:

...
// 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);
        }
    }
});
...

I inserted three dummy contacts in the list to begin with. Clicking on one runs fine, but clicking on another throws the error. In the error below, I clicked on the second entry.

Console output:

...
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]

It looks like it runs correctly, and then runs again and crashes. What (probably obvious thing) am I missing? Thank you for your time and any help you can provide.

It is pretty clear:

Both: false
Both: false
_selectedIndex: -1
lstContacts.getSelectedIndex: -1
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1

The selected index is -1 is the same as doing:

_contactList.get(-1);

Remember, almost all collections in java need an index >= 0.

I think you should modify your condition in order to check if the user have (or not) selected an item in the list so you can handle the error. Something like:

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

Hope it helps.

Happy coding!

Efra

As the comments to your post indicate, it's likely that some other thread is updating your list and unselecting everything by the time you check its value with JList.getSelectedIndex(). You haven't shown all your code, but you probably are doing something with lstContacts later on that is clearing out all the selections in your list.

Since you want to respond to a specific event, don't check the values selected on the list, which, in a multi-threaded environment, might change from one instant to the next. Instead check the value selected by the event with ListSelectionEvent.getFirstIndex()) , which should be constant for that event.

You might find Oracle's Concurrency In Swing tutorial helpful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM