FXML/JavaFX中的多个但有限的复选框



我正在尝试找到一种方法,使用复选框允许用户从三个列表中选择两个,然后禁用其余复选框,直到其中一个被取消选中。我有一个ChangeListener附加到所有三个复选框,所以我可以注册当两个已被选中,但我不知道如何针对"其他"框/框禁用/启用它们。

ChangeListener checkboxlistener = new ChangeListener() {
int i = 0;
        @Override
        public void changed(ObservableValue observable, Object oldValue, Object newValue) {

            if((boolean) observable.getValue() == true) {
                i++;
                System.out.println(i);
            } else {
                i--;
                System.out.println(i);
            }
            if(i == 2) {
                //What should I put here, if anything?//
            }
        }
};
    checkbox1.selectedProperty().addListener(checkboxlistener);
    checkbox2.selectedProperty().addListener(checkboxlistener);
    checkbox3.selectedProperty().addListener(checkboxlistener);
}

保留选中复选框和未选中复选框的集合。向每个复选框的selectedProperty添加一个侦听器,并确保当选择更改时它在正确的集合中。

那么您可以只观察选中复选框集合的大小,并相应地更新所有未选中复选框的disable状态。

下面是一个例子:

MultipleCheckBoxExampleController.java:

package multiplecheckbox;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.IntegerBinding;
import javafx.collections.FXCollections;
import javafx.collections.ObservableSet;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
public class MultipleCheckBoxExampleController {
    @FXML
    private CheckBox checkBox1 ;
    @FXML
    private CheckBox checkBox2 ;
    @FXML
    private CheckBox checkBox3 ;
    @FXML
    private Button submitButton ;
    private ObservableSet<CheckBox> selectedCheckBoxes = FXCollections.observableSet();
    private ObservableSet<CheckBox> unselectedCheckBoxes = FXCollections.observableSet();
    private IntegerBinding numCheckBoxesSelected = Bindings.size(selectedCheckBoxes);
    private final int maxNumSelected =  2; 
    public void initialize() {
        configureCheckBox(checkBox1);
        configureCheckBox(checkBox2);
        configureCheckBox(checkBox3);
        submitButton.setDisable(true);
        numCheckBoxesSelected.addListener((obs, oldSelectedCount, newSelectedCount) -> {
            if (newSelectedCount.intValue() >= maxNumSelected) {
                unselectedCheckBoxes.forEach(cb -> cb.setDisable(true));
                submitButton.setDisable(false);
            } else {
                unselectedCheckBoxes.forEach(cb -> cb.setDisable(false));
                submitButton.setDisable(true);
            }
        });

    }
    private void configureCheckBox(CheckBox checkBox) {
        if (checkBox.isSelected()) {
            selectedCheckBoxes.add(checkBox);
        } else {
            unselectedCheckBoxes.add(checkBox);
        }
        checkBox.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
            if (isNowSelected) {
                unselectedCheckBoxes.remove(checkBox);
                selectedCheckBoxes.add(checkBox);
            } else {
                selectedCheckBoxes.remove(checkBox);
                unselectedCheckBoxes.add(checkBox);
            }
        });
    }
}

MultipleCheckBoxExample.fxml:

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="multiplecheckbox.MultipleCheckBoxExampleController"
     alignment="center" spacing="5">
    <padding>
        <Insets top="10" bottom="10" left="10" right="10" />
    </padding>
    <CheckBox fx:id="checkBox1" text="Choice 1" />
    <CheckBox fx:id="checkBox2" text="Choice 2" />
    <CheckBox fx:id="checkBox3" text="Choice 3" />
    <Button fx:id="submitButton" text="Submit" />
</VBox>

Main.java:

package multiplecheckbox;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.fxml.FXMLLoader;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            VBox root = FXMLLoader.load(getClass().getResource("MultipleCheckBoxExample.fxml"));
            Scene scene = new Scene(root,400,400);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        launch(args);
    }
}

最新更新