私は、ユーザーが時間帯を指定することができますJavaFXのUIを持っています。それは2つのDatePickers、時間スパンの終了日を選択するための開始日と1を選択するための1つの構成されています。
もちろん、私は、ユーザーが終了日とその逆の後にあることを、開始日を選択することができるようにしたくありません。
私はすでにカスタム設定したDayCellFactory
で説明したように、両方の日付ピッカーのためのhttps://stackoverflow.com/a/46372951/5801146。DatePickersの初期化時に指定した最初の時間帯のために意図したように、これは動作します。ただし、ユーザーが選択した場合には、例えば、異なる開始日のために、終了日の日付ピッカーはまだ初期選択可能な日数を示し、新たな開始日にその選択可能な日数を適応しません。もちろん- -ここでは、プロパティリスナー、使用して私のアプローチの仕事をしませんが。
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));
}
};
}
}
私は何を達成したいことは、あなたが現在の値に開始日日付ピッカーの現在値、および開始日の日付ピッカーの最大値に終了日の日付ピッカーの最小値をバインドすることができますWPF / UWPのように結合のいくつかの並べ替えです終了日の日付ピッカーの。どのように私はJavaFXの中で、この動作を達成することができますか?
最初に渡すことができますDatePicker
秒1にの値を、それが変化した後は、第2 1を更新します。
ここでは簡単な例です:
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
}
}
}
}
私は2つの異なるクラスを作成しましたが、私はそれはどんな条件が日付を無効にする場合、それははるかに一般的な、あなたはその中で使用することができ作るためにいくつかの空想の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));