Buddhi
Buddhi

Reputation: 95

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.

Upvotes: 2

Views: 2799

Answers (3)

user19794
user19794

Reputation: 1

Try the following

private void addInvoiceNoItemChangeListener() {
    jcbInvoiceNos.addItemListener(new ItemListener(){
        @Override
        public void itemStateChanged(ItemEvent e){
            if(e.getText() != null && 0 < e.getText()){
                if(e.getStateChange() == ItemEvent.SELECTED){
                    loadInvoiceDetails();
                }
            }
        }
    });
}

This works because it blocks null event texts, and/or text strings that are zero in length, it might be wise to increase zero to one or better two if you know your minimum string to be bigger than two!.

Upvotes: -1

kleopatra
kleopatra

Reputation: 51524

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());
}

Upvotes: 3

StanislavL
StanislavL

Reputation: 57381

I would prevent listener calls when adding items in the combo.

There are 2 ways to do this.

  1. Remove the listener before the adding and readd after

  2. Add a flag isAPI. Set it before adding and reset after. In the listener just check the flag and if it's true just return.

Upvotes: 2

Related Questions