javaswingjcomboboxitemlistener

How i stop triggering swing JCombo Box item listener while adding item to combo box.


I want a JCombox which contain list of invoices. if i select a invoice it will fill the form. invoices are loaded by selecting "buyer" combo box. invoices combox has itemStateChanged event. problem is when i select the buyer, form fills with first invoice(first item in invoice combo box). so i set selected index in to -1 in invoice combo box. same result i got.

Order's toString methos returns the invoice number.


for (Order O : orderList) {
    jcbInvoiceNos.addItem(O);
} 

jcbInvoiceNos.setSelectedIndex(-1);

 private void addInvoiceNoItemChangeListener() {
        jcbInvoiceNos.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    loadInvoiceDetails();
                }
            }
        });
    }

public void loadInvoiceDetails() {
    System.out.println("Selected index " + jcbInvoiceNos.getSelectedIndex());
}

this always prints Selected index 0 this should be Selected index -1 first time i select the buyer. i want to l fill for by selecting invoice. not the buyer.

please give me a solution for this.


Solution

  • The reason for this is the implementation of DefaultComboBoxModel: when adding the first item into an empty model, it automatically selects that first item. It's slight inconsistency is that it does so only when using the addElement(Object) not when using insertElement(Object, size) So the clean (slight cough, modulo relying on an undocumented implementation detail ;-) is to use the latter:

    // loading the invoice ids
    combo.removeAllItems();
    for (int i = 0; i < 20; i++) {
        combo.insertItemAt("combo: " + count + " item: " + i, i);
    }
    

    On the other hand, it might be more user-friendly to present an "informational" selected item (like f.i. "no invoice selected") initially. This can be done if you fill the model (instead of the combo, which doesn't accept selected items that are not contained in the list), something like:

    // the informational item
    Object noInvoice = "no invoice selected";
    
    // loading the invoice ids
    model.removeAllElements();
    model.setSelectedItem(noInvoice);
    for (int i = 0; i < 20; i++) {
        model.addElement("model: " + count + " item: " + i);
    }
    
    // the itemListener ignoring the informational item
    if (ItemEvent.SELECTED == e.getStateChange()) {
        if (noInvoice.equals(e.getItem())) return; 
        doLoadDetails(e.getItem());
    }