我正在尝试找到一种方法,使用复选框允许用户从三个列表中选择两个,然后禁用其余复选框,直到其中一个被取消选中。我有一个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);
}
}