JavaFX更新组合框项目列表,以基于可变输入禁用某些项目
我正在为预订系统开发一个界面。在一个窗口中,我需要获得预定的开始时间和预定的结束时间,以便检查db是否有该时段可用。只有hh:嗯,我有兴趣,我在其他地方得到了这一天。 组合框如下所示:JavaFX更新组合框项目列表,以基于可变输入禁用某些项目,java,javafx,combobox,Java,Javafx,Combobox,我正在为预订系统开发一个界面。在一个窗口中,我需要获得预定的开始时间和预定的结束时间,以便检查db是否有该时段可用。只有hh:嗯,我有兴趣,我在其他地方得到了这一天。 组合框如下所示: //startTime HBox HBox startTime = new HBox(); startTime.setSpacing(5); final ComboBox startHours = new ComboBox(hours); final ComboBox startM
//startTime HBox
HBox startTime = new HBox();
startTime.setSpacing(5);
final ComboBox startHours = new ComboBox(hours);
final ComboBox startMinutes = new ComboBox(minutes);
final Label colon = new Label(":");
startTime.getChildren().addAll(startHours,colon,startMinutes);
endTimean HBox的情况也一样,它的组件相同,只是变量名发生了变化
我希望startTime-hour组合框自动禁用高于当前endTime组合框小时数的项目,反之亦然,我希望禁用低于startTime-hour组合框的endTime-hour项目。
我曾经尝试创建一个单元格工厂,但是如果我在编辑另一个组合框之前打开组合框,它就不起作用了
startHours.setCellFactory(
new Callback<ListView<String>, ListCell<String>>() {
@Override
public ListCell<String> call(ListView<String> param) {
final ListCell<String> cell = new ListCell<String>() {
@Override public void updateItem(String item,
boolean empty) {
super.updateItem(item, empty);
if (item!=null){
setText(item);
}
if ((endHours.getValue()!=null) && (endHours.getValue().toString().compareTo(item)<0)){
setDisable(true);
setStyle("-fx-background-color: #ffc0cb");
}
}
};
return cell;
}
});
您的单元格需要观察另一个组合框中的值,以便在该组合框中的值发生更改时知道如何更新其禁用状态 注意,单元格实现中还有其他错误:您必须考虑updateItem方法中的所有可能性:例如,您没有正确处理项目为null、单元格为空,或者在需要时将禁用状态设置回false。最后,在这里使用字符串作为数据类型既不方便,又可能需要在某个时候转换回int来使用这些值,并且会弄乱逻辑,例如,因为10小于2。你应该在这里使用组合框 下面是一个仅包含两个小时组合框的实现:
import java.util.function.BiPredicate;
import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class DependentComboBoxes extends Application {
private ComboBox<Integer> startHours ;
private ComboBox<Integer> endHours ;
@Override
public void start(Stage primaryStage) {
startHours = new ComboBox<>();
endHours = new ComboBox<>();
startHours.setCellFactory(lv -> new StartHoursCell());
endHours.setCellFactory(lv -> new EndHoursCell());
for (int i = 0; i < 24 ; i++) {
startHours.getItems().add(i);
endHours.getItems().add(i);
}
GridPane root = new GridPane();
root.setHgap(5);
root.setVgap(5);
root.addRow(0, new Label("Start hours:"), startHours);
root.addRow(1, new Label("End hours:"), endHours);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(20));
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
private class StartHoursCell extends ListCell<Integer> {
StartHoursCell() {
endHours.valueProperty().addListener((obs, oldEndHours, newEndHours) -> updateDisableState());
}
@Override
protected void updateItem(Integer hours, boolean empty) {
super.updateItem(hours, empty);
if (empty) {
setText(null);
} else {
setText(hours.toString());
updateDisableState();
}
}
private void updateDisableState() {
boolean disable = getItem() != null && endHours.getValue() != null &&
getItem().intValue() > endHours.getValue();
setDisable(disable) ;
setOpacity(disable ? 0.5 : 1);
}
}
private class EndHoursCell extends ListCell<Integer> {
EndHoursCell() {
startHours.valueProperty().addListener((obs, oldEndHours, newEndHours) -> updateDisableState());
}
@Override
protected void updateItem(Integer hours, boolean empty) {
super.updateItem(hours, empty);
if (empty) {
setText(null);
} else {
setText(hours.toString());
updateDisableState();
}
}
private void updateDisableState() {
boolean disable = getItem() != null && startHours.getValue() != null &&
getItem().intValue() < startHours.getValue();
setDisable(disable) ;
setOpacity(disable ? 0.5 : 1);
}
}
public static void main(String[] args) {
launch(args);
}
}
没有那么复杂,但不禁用组合框中的项目将是单独保留startHours,并使用所选的值来确定endHours中显示的内容。当startHours值更改时,它将用从开始到23的所有小时填充endHours。如果已经选择了endHours,并且您将startHours更改为更高的值,那么它将不会显示任何内容,并且必须重新选择。startHours中的值不应该改变,只是endHours中的值
这是一个非常令人惊讶的答案,詹姆斯·D。。这将对我有很大帮助…同时,我在操作事件的提交按钮中进行了一些错误检查,因为我认为这种方法太复杂了。然而,你的回答证明这并不难。但愿有人在我旁边解释听众和事件之间的区别:d同时,非常感谢
ComboBox<Integer> start = new ComboBox<Integer>();
ComboBox<Integer> end = new ComboBox<Integer>();
for(int i : IntStream.range(1, 24).toArray()) {
start.getItems().add(i);
end.getItems().add(i);
}
start.setOnAction(ae -> {
Integer selected = end.getSelectionModel().getSelectedItem();
end.getItems().clear();
for(int i : IntStream.range(start.getSelectionModel().getSelectedItem(), 24).toArray()) {
end.getItems().add(i);
}
if(end.getItems().contains(selected)) {
end.getSelectionModel().select(selected);
}
});