I have a list of Map.Entry<String,Integer>s that I am looping through, and for each one, making a JLabel/JSpinner representing that particular entry.
How can I make it so that when the ChangeListener fires on the JSpinner, it updates that entry to reflect the new value?
My code looks like
for (Map.Entry<String,Integer> entry : graph.getData()) {
SpinnerNumberModel model = new SpinnerNumberModel(
entry.getValue(),(Integer)0,(Integer)100,(Integer)5);
JSpinner spinner = new JSpinner(model);
JLabel label = new JLabel(entry.getKey());
spinner.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
entry.setValue((Integer)((JSpinner)e.getSource()).getValue());
}
});
// more stuff
}
However, this does not work, because entry either needs to be final or object-level, and it is neither.
Is there an easier way, like C#’s dataSource that directly binds the object to the spinner? Or how can I make this work?
There are several options if you want to stick with individual
JLabelandJSpinner. Use @trashgod’s answer if the map could get large.final Map.Entry<String,Integer> entryspinner.putClientProperty("MyEntryKey", entry), then in your ChangeListener get the entry withspinner.getClientProperty.spinner.putClientProperty("MyEntryKey", entry.getKey()), then in your ChangeListenergraph.put(spinner.getClientProperty(), ...).final String key = entry.getKey(), then in your ChangeListenergraph.put(key, ...).Let your enclosing class implement
ChangeListenerto avoid oneChangeListenerperJSpinner:public void stateChanged(ChangeEvent e) {
JSpinner spinner = (JSpinner)e.getSource();
graph.put((String)spinner.getClientProperty(“MyEntryKey”), (Integer)spinner.getValue());
}
BTW
graph.getData()looks a bit odd. IfgraphimplementsMap, you should usegraph.entrySet().