JCheckBox' value resets / doesn't change
I have several components, all inheriting JCheckBox without overwriting anything from it, stored in a vector, which is then traversed and each of the components is added to a dialog
CreateLists(); // initialises the checkbox vector
for(int i = 0; i < checkBoxes.size() ; i++){
myPanel.add(checkBoxes.elementAt(i));
}
Some of these checkboxes are already selected.
My problem now is: When I open the dialog and select or unselect any checkbox, the value of the checkboxes in the vector doesn't change. Selected stays selected and unselected stays unselected.
I also tryed to get the new values by using JPanels getCompoents(), but the values of these are wrong, too. An ItemListener in the checkbox开发者_JAVA技巧 inheritors confirmes that the changes do happen, but whenever I try to get the new values, there just the same as those with which the checkboxes were initialised.Here is a console output I used to keep track of the changes:
create lists
print values:
checkBox1 = true
checkBox2 = true
checkBox3 = false
checkBox2 clicked new value = false
checkBox3 clicked new value = true
print values:
checkBox1 = true
checkBox2 = true
checkBox3 = false
Here is some more code and information:
CreateList() compares a watchlist with the watchable things, creates the checkboxes accordingly (true = watched etc) and adds them to the new initalised vector.
To read the values i use this:
Component[] components = pnlGesamt.getComponents();
for(int i = 0; i < components.length; i++){
if(components[i] instanceof WLElementCheckBox){
WLElementCheckBox cb = (WLElementCheckBox) components[i];
System.out.println(cb.WlElement().Name() + " = " + cb.isSelected());
}
}
The JCheckBox inheritor:
private WatchListElement wlElement;
public WLElementCheckBox (WatchListElement wl, boolean selected)
{
super();
WlElement(wl);
setSelected(selected);
setText(wlElement.Name());
addItemListener(new MIL());
}
public WatchListElement WlElement ()
{
return wlElement;
}
public void WlElement (WatchListElement wlElement)
{
this.wlElement = wlElement;
}
public class MIL implements ItemListener{
public void itemStateChanged(ItemEvent arg0) {
System.out.println("Ckb " + wlElement.Name() +" geklickt Item neu = " + isSelected());
}
}
There is a small possibility that the changes to your checkboxes are not visible because you're querying them from another thread (such as main) instead of the Event Dispatch Thread (EDT). Swing is not thread-safe. When you check the checkboxes, the values are set on the EDT, but other threads might have the old state saved in memory and don't check to see if it's been updated. So, the first thing you need to do is ensure that when you're checking the states of your checkboxes, you're doing it from the EDT, using a call to SwingUtilities.invokeAndWait()
or SwingUtilities.invokeLater()
.
For more information on why this happens, search for Thread Safety in Java.
(Also, don't be tempted to use synchronization to solve the problem or you might end up with a deadlock in your GUI).
One final pro tip: using new Java for-loop syntax makes code easier to read and write, as well as more efficient in some cases. Your code...
for(int i = 0; i < checkBoxes.size() ; i++){
myPanel.add(checkBoxes.elementAt(i));
}
... can turn into...
for(JCheckBox c : checkBoxes) {
myPanel.add(c);
}
This works on arrays and anything that is Iterable
(which includes Collection
).
精彩评论