FaithReaper FaithReaper - 3 months ago 10
Java Question

Why my Array of JComboBox are not updated?

I create a field of

Object[]
named
array
:

private Object[] array;


And then I initiate it with dimension and add
JComboBox
into it in method A:

array = new Object[14];
array[0] = combo1;
array[1] = combo2;
....


Then, I changed the data model of these
JComboBox
in method B,
changeCombo
.

private JComboBox<String> changeCombo(String newOption, JComboBox<String> combo, Set<String> data) {
if (combo != null) {
int size = combo.getModel().getSize();
data.add(newOption);
if (size != data.size()){
combo = updateCombo(data);
}
return combo;
}
}


Where
updateCombo(data)
is:

private JComboBox<String> updateCombo(Set<String> dataSet) {
JComboBox<String> combo = new JComboBox<String>();
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
model.insertElementAt(Constantes.COMBO_TEXT_TODOS, 0);
for (String s: dataSet) {
model.addElement(s);
}
combo.setModel(model);
combo.setSelectedIndex(0);
combo.addItemListener(new ComboItemListener());
return combo;
}


At last, I invoke this array again in method C, only to find all JComboBox has no data in it.

for (int i=0; i<14; i++ ){
TableColumn col = table.getColumnModel().getColumn(i);
col.setCellEditor(new DefaultCellEditor((JComboBox<String>)(array[i])));
//here I found the data collection in each combo is empty
col.setCellRenderer(new ComboRenderer());
}


So, arrays are immutable in my case? Or these JComboBox are immutable?

Answer

In the updateCombo you create a new instance of JComboBox, but the array contains a link to the old instances

You need to explicitly replace old instances to newer ones returned by changeCombo.
Something like this:

array[i] = changeCombo(newOption, array[i], data);

I think, In your case, it is better to reuse existing instance of combo - just change it's model to the newer one. Or more - modify existing model.

For example, you can replace updateCombo with updateComboModel:

private void replaceComboModel(JComboBox<String> combo, Set<String> dataSet) {
    DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
    model.insertElementAt(Constantes.COMBO_TEXT_TODOS, 0);
    for (String s: dataSet) {
        model.addElement(s);
    }
    combo.setModel(model);
}

And just call replaceComboModel(combo, data) instead of combo = updateCombo(data) inside changeCombo

I may miss some swing internals,

This topic can also help you understand the nature of object references - Object References