bind two ToggleButtons to a BooleanProperty

I have two ToggleButtons and I would like them both to be bound to a Boolean property so that when one ToggleButton is selected, the other ToggleButton isn't, and the BooleanProperty is true, and vice versa.

Here's what I tried.

FXML file:

<VBox xmlns:fx="http://javafx.com/fxml" fx:controller="my.package.MainController" styleClass="Tool" fx:id="root">
<HBox spacing="10">
    <fx:define>
        <ToggleGroup fx:id="modeToggleGroup"/>
    </fx:define>
    <ToggleButton fx:id="manualModeBtn" text="Manual Mode" selected="true" toggleGroup="$modeToggleGroup"/>
    <ToggleButton fx:id="automaticModeBtn" text="Automatic Mode" toggleGroup="$modeToggleGroup"/>
</HBox>
<!-- other stuff -->
</VBox>

Controller file:

public class MainController {

    @FXML
    private ToggleButton manualModeBtn;
    @FXML
    private ToggleButton automaticModeBtn;

    private BooleanProperty isAutomaticMode;

    public void initialize() {
        isAutomaticMode = new SimpleBooleanProperty();
        automaticModeBtn.selectedProperty.bindBidirectional(isAutomaticMode);
    }
}

The ToggleGroup ensures that neither button is selected at the same time, but I can still unselect both of them, which I don't want to be possible.

How do I bind the other ToggleButton to the opposite (i.e. not()) of the Boolean Property?

2 answers

  • answered 2018-01-11 20:35 James_D

    You could do this by using listeners:

    public class MainController {
    
        @FXML
        private ToggleButton manualModeBtn;
        @FXML
        private ToggleButton automaticModeBtn;
    
    
        public void initialize() {
            manualModeBtn.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> automaticModeBtn.setSelected(! isNowSelected));
            automaticModeBtn.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> manualModeBtn.setSelected(! isNowSelected));
    
        }
    }
    

    Note that RadioButton has almost this functionality already (in the case of a radio button, you can't "deselect" it), so you could simply use RadioButtons instead. Note this question, if it is just a case of how they look.

  • answered 2018-01-11 20:55 Sedrick

    This can also be done by setting a listener on the ToggleGroup's selectedToggleProperty.

    You first have to set an initial button.

    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.control.ToggleButton;
    import javafx.scene.control.ToggleGroup;
    import javafx.scene.layout.HBox;
    import javafx.stage.Stage;
    
    public class ToggleButtonExperiments extends Application
    {
    
        @Override
        public void start(Stage primaryStage) throws Exception
        {
            primaryStage.setTitle("HBox Experiment 1");
    
            ToggleButton toggleButton1 = new ToggleButton("Left");
            ToggleButton toggleButton2 = new ToggleButton("Right");
    
            ToggleGroup toggleGroup = new ToggleGroup();
            toggleButton1.setSelected(true);//set initial button!!!!!
    
            toggleGroup.selectedToggleProperty().addListener((obs, oldTog, newTog) -> {
                if (newTog == null) {
                    oldTog.setSelected(true);
                }
            });
    
            toggleButton1.setToggleGroup(toggleGroup);
            toggleButton2.setToggleGroup(toggleGroup);
    
            HBox hbox = new HBox(toggleButton1, toggleButton2);
    
            Scene scene = new Scene(hbox, 200, 100);
            primaryStage.setScene(scene);
            primaryStage.show();
    
        }
    
        public static void main(String[] args)
        {
            Application.launch(args);
        }
    }