Button of Choice: Use ToggleButtons as RadioButtons
For MQTT.fx I wanted to use ToggleButtons to e.g. choose the de coding of a MQTT Message or the QoS Level:
I found out that in context of a ToggleGroup ToggleButtons behave different than RadioButtons in terms of selection/deselection: unlike RadioButtons ToggleButtons can still be set to unselected state.
A RadioButton extends ToggleButton and overrides fire() (which is invoked when a user gesture indicates that an event for this ButtonBase should occur aka “Button was clicked”):
RadioButton:
@Override public void fire() {
// we don't toggle from selected to not selected if part of a group
if (getToggleGroup() == null || !isSelected()) {
super.fire();
}
}ToggleButton:
@Override public void fire() {
setSelected(!isSelected());
fireEvent(new ActionEvent());
}In a ToogleGroup ToggleButtons should behave like RadioButtons, so IMHO this is a bug worth a pull request for ToggleButton ��
One way to handle this is for sure to create a custom extension of ToggleButton implementing fire() in respect to the RadioButton.
But I like more to add behavior to existing controls.
This is my tweak to modify default behavior by adding filters to all ToogleButtons of a ToggleGroup consuming unwanted MouseEvents:
public class JavaFXUtil {
private static JavaFXUtil me;
private JavaFXUtil() {
}
public static JavaFXUtil get() {
if (me == null) {
me = new JavaFXUtil();
}
return me;
}
public EventHandler<MouseEvent> consumeMouseEventfilter = (MouseEvent mouseEvent) -> {
if (((Toggle) mouseEvent.getSource()).isSelected()) {
mouseEvent.consume();
}
};
public void addAlwaysOneSelectedSupport(final ToggleGroup toggleGroup) {
toggleGroup.getToggles().addListener((Change<? extends Toggle> c) -> {
while (c.next()) {
for (final Toggle addedToggle : c.getAddedSubList()) {
addConsumeMouseEventfilter(addedToggle);
}
}
});
toggleGroup.getToggles().forEach(t -> {
addConsumeMouseEventfilter(t);
});
}
private void addConsumeMouseEventfilter(Toggle toggle) {
((ToggleButton) toggle).addEventFilter(MouseEvent.MOUSE_PRESSED, consumeMouseEventfilter);
((ToggleButton) toggle).addEventFilter(MouseEvent.MOUSE_RELEASED, consumeMouseEventfilter);
((ToggleButton) toggle).addEventFilter(MouseEvent.MOUSE_CLICKED, consumeMouseEventfilter);
}
}public class ButtonDemoController {
@FXML
private ToggleGroup g2;
@FXML
private ToggleGroup g3;
public void initialize() {
JavaFXUtil.get().addAlwaysOneSelectedSupport(g2);
JavaFXUtil.get().addAlwaysOneSelectedSupport(g3);
}
}Example code at GitHub.
| Reference: | Button of Choice: Use ToggleButtons as RadioButtons from our JCG partner Jens Deters at the JavaFX Delight blog. |









I love toggle buttons just because they’re a break from the norm, but I think they might be confusing for people who aren’t familiar with them. And yes, of course I realize they’re totally intuitive and it’s fairly obvious how they work, but you know how it is…