gpt4 book ai didi

java - 使用一个 DatePicker 的当前值作为另一个 DatePicker 的最小值/最大值

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:37:19 24 4
gpt4 key购买 nike

我有一个允许用户指定时间跨度的 JavaFX UI。它由两个 DatePicker 组成,一个用于选择时间跨度的开始日期,一个用于选择结束日期。

显然,我不希望用户能够选择晚于结束日期的开始日期,反之亦然。

我已经为两个日期选择器设置了自定义 DayCellFactory,如 https://stackoverflow.com/a/46372951/5801146 中所述.这适用于 DatePickers 初始化期间指定的初始时间范围。但是,如果用户随后选择了一个不同的开始日期,例如,结束日期 DatePicker 仍会显示初始可选日期并且不会将其可选日期调整为新的开始日期。这是我使用属性监听器的方法,当然,它不起作用:

public final class DatePickerUtil {

public static void constrainLowerUpperBounds(DatePicker lowerBoundDatePicker, DatePicker upperBoundDatePicker) {
LocalDate lowerBound = lowerBoundDatePicker.getValue();
LocalDate upperBound = upperBoundDatePicker.getValue();

if (lowerBound.isAfter(upperBound)) {
throw new IllegalStateException("Upper bound date picker has older date than lower bound date picker");
}

lowerBoundDatePicker.setEditable(true);
upperBoundDatePicker.setEditable(true);

lowerBoundDatePicker.setDayCellFactory(createDayCellFactory(null, upperBound));
upperBoundDatePicker.setDayCellFactory(createDayCellFactory(lowerBound, null));

lowerBoundDatePicker.valueProperty().addListener((observable, oldValue, newValue) -> {
upperBoundDatePicker.setDayCellFactory(createDayCellFactory(newValue, null));
});

upperBoundDatePicker.valueProperty().addListener(((observable, oldValue, newValue) -> {
lowerBoundDatePicker.setDayCellFactory(createDayCellFactory(null, newValue));
}));
}

private static Callback<DatePicker, DateCell> createDayCellFactory(LocalDate lowerBound, LocalDate upperBound) {
return picker -> new DateCell() {
@Override
public void updateItem(LocalDate date, boolean empty) {
super.updateItem(date, empty);
boolean isBeforeLowerBound = lowerBound != null && date.isBefore(lowerBound);
boolean isAfterUpperBound = upperBound != null && date.isAfter(upperBound);
Platform.runLater(() -> setDisable(empty || isBeforeLowerBound || isAfterUpperBound));
}
};
}
}

我想要实现的是某种绑定(bind),就像在 WPF/UWP 中一样,您可以将结束日期 DatePicker 的最小值绑定(bind)到开始日期 DatePicker 的当前值,并将开始日期 DatePicker 的最大值绑定(bind)到结束日期 DatePicker 的当前值。我怎样才能在 JavaFX 中实现这种行为?

最佳答案

您可以将第一个 DatePicker 的值传递给第二个,并在它更改后更新第二个。

这是一个简单的例子:

public class MinMaxDate {

private void test() {
DatePicker firstDP = new DatePicker();
DatePicker secondDP = new DatePicker();

// set the min date
secondDP.setDayCellFactory(cf -> new MinDateCell(firstDP.valueProperty()));
// set the max date
secondDP.setDayCellFactory(cf -> new MaxDateCell(firstDP.valueProperty()));
}

private class MinDateCell extends DateCell {

private ObjectProperty<LocalDate> date;

private MinDateCell(ObjectProperty<LocalDate> date) {
this.date = date;
}

@Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
if (item.isBefore(date.get())) {
this.setDisable(true);
setStyle("-fx-background-color: #7e7e7e;"); // I used a different coloring to see which are disabled.
}
}

}

private class MaxDateCell extends DateCell {

private ObjectProperty<LocalDate> date;

private MaxDateCell(ObjectProperty<LocalDate> date) {
this.date = date;
}

@Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
if (item.isAfter(date.get())) {
this.setDisable(true);
setStyle("-fx-background-color: #7e7e7e;"); // Same here
}
}

}

}

我已经创建了两个不同的类,但我相信可以使用一些奇特的 java8 函数来解决它,使其更通用,然后您可以在任何情况下使用它来禁用日期。

更新

这是通用的解决方案:

private class FilterDateCell extends DateCell {

private ObjectProperty<LocalDate> date;
private BiPredicate<LocalDate, LocalDate> filterPredicate;

private FilterDateCell(
ObjectProperty<LocalDate> date,
BiPredicate<LocalDate, LocalDate> filterPredicate) {
this.date = date;
this.filterFunction = filterFunction;
}

@Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
if (filterPredicate.test(item, date.get())) {
this.setDisable(true);
setStyle("-fx-background-color: #7e7e7e;"); // I used a different coloring to see which are disabled.
}
}

}

它可以像这样使用:

// set the min date
secondDP.setDayCellFactory(cf -> new FilterDateCell(firstDP.valueProperty(),LocalDate::isBefore));
// set the max date
secondDP.setDayCellFactory(cf -> new FilterDateCell(firstDP.valueProperty(),LocalDate::isAfter));

关于java - 使用一个 DatePicker 的当前值作为另一个 DatePicker 的最小值/最大值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56376959/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com