在 DatePicker 中禁用日期而不启用以前禁用的日期
Disabling dates in DatePicker without enabling previously disabled dates
import java.time.DayOfWeek;
import java.time.LocalDate;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.control.Button;
import javafx.scene.control.DateCell;
import javafx.scene.control.DatePicker;
import javafx.scene.layout.VBox;
public class Example extends Application {
@Override public void start(Stage stage) {
VBox container = new VBox();
DatePicker datePicker = new DatePicker();
disableSomeDates(datePicker);
Button disableMondaysButton = new Button("No Mondays!");
disableMondaysButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent arg0) {
disableSomeMoreDates(datePicker);
}
});
container.getChildren().add(datePicker);
container.getChildren().add(disableMondaysButton);
Scene scene = new Scene(container);
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
public void disableSomeDates(DatePicker datePicker) {
datePicker.setDayCellFactory(param -> new DateCell() {
@Override
public void updateItem(LocalDate date, boolean empty) {
super.updateItem(date, empty);
//Disables dates before current date
setDisable(empty || date.compareTo(LocalDate.now()) < 0 );
}
});
}
public void disableSomeMoreDates(DatePicker datePicker) {
datePicker.setDayCellFactory(param -> new DateCell() {
@Override
public void updateItem(LocalDate date, boolean empty) {
super.updateItem(date, empty);
//Disables mondays
setDisable(empty || date.getDayOfWeek() == DayOfWeek.MONDAY);
}
});
}
}
在这个示例代码中,我创建了一个 DatePicker 并禁用了一些日期(今天之前的日期)。然后按下按钮,它应该禁用星期一,因此我们应该禁用今天之前的所有日期和所有星期一。在这种情况下,我们最终将只禁用星期一。
如何使按钮禁用星期一而不重新启用今天之前的日期?
我建议使用单个细胞工厂,生成观察可以更改的属性的细胞。
例如:
import java.time.DayOfWeek;
import java.time.LocalDate;
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.DateCell;
import javafx.scene.control.DatePicker;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Example extends Application {
@Override public void start(Stage stage) {
BooleanProperty mondaysDisabled = new SimpleBooleanProperty(false);
VBox container = new VBox();
DatePicker datePicker = new DatePicker();
datePicker.setDayCellFactory(dp -> new DateCell() {
{
mondaysDisabled.addListener((obs, mondaysWereDisabled, mondaysAreNowDisabled)
-> updateDisabledStatus());
}
@Override
public void updateItem(LocalDate date, boolean empty) {
super.updateItem(date, empty);
updateDisabledStatus();
}
private void updateDisabledStatus() {
if (isEmpty()) {
setDisable(true);
} else {
LocalDate date = getItem();
if (date.isBefore(LocalDate.now())) {
setDisable(true);
} else {
if (mondaysDisabled.get() && date.getDayOfWeek() == DayOfWeek.MONDAY) {
setDisable(true);
} else {
setDisable(false);
}
}
}
}
});
Button disableMondaysButton = new Button("No Mondays!");
disableMondaysButton.setOnAction(event -> mondaysDisabled.set(true));
container.getChildren().add(datePicker);
container.getChildren().add(disableMondaysButton);
Scene scene = new Scene(container);
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
对于更模块化的方法,您可以保留一个可观察的过滤器列表以供检查。例如
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.function.Predicate;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.DateCell;
import javafx.scene.control.DatePicker;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Example extends Application {
@Override public void start(Stage stage) {
ObservableList<Predicate<LocalDate>> dayFilters = FXCollections.observableArrayList();
dayFilters.add(date -> date != null);
dayFilters.add(date -> ! date.isBefore(LocalDate.now()));
VBox container = new VBox();
DatePicker datePicker = new DatePicker();
datePicker.setDayCellFactory(dp -> new DateCell() {
{
dayFilters.addListener((Change<? extends Predicate<LocalDate>> change) -> updateDisabledStatus());
}
@Override
public void updateItem(LocalDate date, boolean empty) {
super.updateItem(date, empty);
updateDisabledStatus();
}
private void updateDisabledStatus() {
setDisable(false);
for (Predicate<LocalDate> check : dayFilters) {
if (! check.test(getItem())) {
setDisable(true);
break ;
}
}
}
});
Button disableMondaysButton = new Button("No Mondays!");
disableMondaysButton.setOnAction(event -> dayFilters.add(date -> date.getDayOfWeek() != DayOfWeek.MONDAY));
container.getChildren().add(datePicker);
container.getChildren().add(disableMondaysButton);
Scene scene = new Scene(container);
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
import java.time.DayOfWeek;
import java.time.LocalDate;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.control.Button;
import javafx.scene.control.DateCell;
import javafx.scene.control.DatePicker;
import javafx.scene.layout.VBox;
public class Example extends Application {
@Override public void start(Stage stage) {
VBox container = new VBox();
DatePicker datePicker = new DatePicker();
disableSomeDates(datePicker);
Button disableMondaysButton = new Button("No Mondays!");
disableMondaysButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent arg0) {
disableSomeMoreDates(datePicker);
}
});
container.getChildren().add(datePicker);
container.getChildren().add(disableMondaysButton);
Scene scene = new Scene(container);
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
public void disableSomeDates(DatePicker datePicker) {
datePicker.setDayCellFactory(param -> new DateCell() {
@Override
public void updateItem(LocalDate date, boolean empty) {
super.updateItem(date, empty);
//Disables dates before current date
setDisable(empty || date.compareTo(LocalDate.now()) < 0 );
}
});
}
public void disableSomeMoreDates(DatePicker datePicker) {
datePicker.setDayCellFactory(param -> new DateCell() {
@Override
public void updateItem(LocalDate date, boolean empty) {
super.updateItem(date, empty);
//Disables mondays
setDisable(empty || date.getDayOfWeek() == DayOfWeek.MONDAY);
}
});
}
}
在这个示例代码中,我创建了一个 DatePicker 并禁用了一些日期(今天之前的日期)。然后按下按钮,它应该禁用星期一,因此我们应该禁用今天之前的所有日期和所有星期一。在这种情况下,我们最终将只禁用星期一。
如何使按钮禁用星期一而不重新启用今天之前的日期?
我建议使用单个细胞工厂,生成观察可以更改的属性的细胞。
例如:
import java.time.DayOfWeek;
import java.time.LocalDate;
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.DateCell;
import javafx.scene.control.DatePicker;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Example extends Application {
@Override public void start(Stage stage) {
BooleanProperty mondaysDisabled = new SimpleBooleanProperty(false);
VBox container = new VBox();
DatePicker datePicker = new DatePicker();
datePicker.setDayCellFactory(dp -> new DateCell() {
{
mondaysDisabled.addListener((obs, mondaysWereDisabled, mondaysAreNowDisabled)
-> updateDisabledStatus());
}
@Override
public void updateItem(LocalDate date, boolean empty) {
super.updateItem(date, empty);
updateDisabledStatus();
}
private void updateDisabledStatus() {
if (isEmpty()) {
setDisable(true);
} else {
LocalDate date = getItem();
if (date.isBefore(LocalDate.now())) {
setDisable(true);
} else {
if (mondaysDisabled.get() && date.getDayOfWeek() == DayOfWeek.MONDAY) {
setDisable(true);
} else {
setDisable(false);
}
}
}
}
});
Button disableMondaysButton = new Button("No Mondays!");
disableMondaysButton.setOnAction(event -> mondaysDisabled.set(true));
container.getChildren().add(datePicker);
container.getChildren().add(disableMondaysButton);
Scene scene = new Scene(container);
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
对于更模块化的方法,您可以保留一个可观察的过滤器列表以供检查。例如
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.function.Predicate;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.DateCell;
import javafx.scene.control.DatePicker;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Example extends Application {
@Override public void start(Stage stage) {
ObservableList<Predicate<LocalDate>> dayFilters = FXCollections.observableArrayList();
dayFilters.add(date -> date != null);
dayFilters.add(date -> ! date.isBefore(LocalDate.now()));
VBox container = new VBox();
DatePicker datePicker = new DatePicker();
datePicker.setDayCellFactory(dp -> new DateCell() {
{
dayFilters.addListener((Change<? extends Predicate<LocalDate>> change) -> updateDisabledStatus());
}
@Override
public void updateItem(LocalDate date, boolean empty) {
super.updateItem(date, empty);
updateDisabledStatus();
}
private void updateDisabledStatus() {
setDisable(false);
for (Predicate<LocalDate> check : dayFilters) {
if (! check.test(getItem())) {
setDisable(true);
break ;
}
}
}
});
Button disableMondaysButton = new Button("No Mondays!");
disableMondaysButton.setOnAction(event -> dayFilters.add(date -> date.getDayOfWeek() != DayOfWeek.MONDAY));
container.getChildren().add(datePicker);
container.getChildren().add(disableMondaysButton);
Scene scene = new Scene(container);
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}