Reputation:
Given:
I have a javafx.scene.control.CheckBox
and I would like to allow 3-states instead of only 2 (selected
and not selected
).
I read about indeterminate
state.
According to JavaDocs http://docs.oracle.com/javafx/2/api/javafx/scene/control/CheckBox.html#allowIndeterminateProperty
checked: indeterminate == false, checked == true
unchecked: indeterminate == false, checked == false
undefined: indeterminate == true
Problem:
I need to allow from indeterminate
to selected
only once
CheckBox checkbox = new CheckBox("Indeterminate");
checkbox.setAllowIndeterminate(true);
checkbox.setIndeterminate(true);
checkbox.setSelected(false);
checkbox.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
if (checkbox.isIndeterminate()) {
checkbox.setSelected(true);
checkbox.setIndeterminate(false);
checkbox.setAllowIndeterminate(false);
checkbox.setText("Checked");
} else if (checkbox.isSelected()) {
checkbox.setSelected(false);
checkbox.setText("Unchecked");
} else if (!checkbox.isSelected()) {
checkbox.setSelected(true);
checkbox.setText("Checked");
}
}
});
Interestingly, when I click on the checkbox for the first time, it goes directly to the else if (checkbox.isSelected())
block!!!
Question:
WHAT???! HOW? Why isn't this working?
What I need is that if it is initially indeterminate, then on the first click, it should become checked. And continue on more clicks: checked -> unchecked, unchecked -> checked, ...
Else if it initially not indeterminate (ie selected or not selected), then it should behave normally: checked -> unchecked, unchecked -> checked, ...
Upvotes: 1
Views: 2635
Reputation: 21799
When you set allowIndeterminateProperty to true, what you actually do is to allow the CheckBox
to cycle all three states:
Determines whether the user toggling the CheckBox should cycle through all three states: checked, unchecked, and undefined. If true then all three states will be cycled through; if false then only checked and unchecked will be cycled.
In your case it should be set to false, as you want it just to cycle between checked and unchecked.
Then if you set indeterminateProperty initially either true or false the CheckBox
will just cycle checked and unchecked states.
The reason why your CheckBox
enters the isSelected branch is the cycle defined in the quote: checked -> unchecked -> undefined -> checked -> .... Your CheckBox
is in undefined state because of checkbox.setIndeterminate(true);
and the next state is checked.
Example
This CheckBox
is initially undefined then it cycles checked and unchecked.
CheckBox checkBox = new CheckBox();
checkBox.indeterminateProperty().set(true);
checkBox.setAllowIndeterminate(false);
checkBox.selectedProperty().addListener((obs, oldVal, newVal) -> {
if(newVal)
System.out.println("Checked");
else
System.out.println("Unchecked");
});
Upvotes: 1