JavaFX извлекает календарь-всплывающее окно из DatePicker / показывает только всплывающее окно
Я пытаюсь создать CalendarView для приложения JavaFX, чтобы отображать только даты (выбор не требуется). Так как DatePicker
У класса есть хорошее всплывающее окно с календарем. Я подумал, что могу попытаться извлечь его, чтобы у меня уже были все вопросы о стиле.
Так есть ли простой способ извлечь всплывающее окно календаря DatePicker и вставить его в новый CalendarView?
Я уже посмотрел на show()
метод из ComboBoxBase
класс, чтобы увидеть, что именно происходит, когда всплывающее окно срабатывает, но я должен признать, что я не мог понять это.
В качестве альтернативы я мог бы подумать о том, чтобы просто отредактировать DatePicker таким образом, чтобы все время отображалось только всплывающее окно с всегда скрываемым компонентом editor-TextField и компонентом button, но, опять же, я не мог понять, как это сделать, не скрывая также всплывающее окно., Также мне, вероятно, понадобится получить границы всплывающего окна, чтобы соответствующим образом управлять высотой и шириной в этом альтернативном варианте, что опять-таки, кажется, не так просто.
2 ответа
Вы можете получить всплывающее содержимое DatePicker из DatePickerSkin. Посмотрите эту демонстрацию для реализации:
public class DatePickerPopupDemo extends Application {
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root, 400, 400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
DatePickerSkin datePickerSkin = new DatePickerSkin(new DatePicker(LocalDate.now()));
Node popupContent = datePickerSkin.getPopupContent();
root.setCenter(popupContent);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Если верхняя панель не нужна, вы можете посмотреть ее и спрятать.
DatePickerSkin datePickerSkin = new DatePickerSkin(new DatePicker(LocalDate.now()));
Node popupContent = datePickerSkin.getPopupContent();
// force a css layout pass to ensure that lookup calls work
popupContent.applyCss();
popupContent.lookup(".month-year-pane").setVisible(false);
root.setCenter(popupContent);
Обновить:
По состоянию на JDK 9 DatePickerSkin
является частью Public API и использует закрытый com.sun.[...]
реализация больше не нужна. (См. JavaDoc)
Кроме того, как упоминалось в комментариях, чтобы получить выбранное значение, вы должны получить доступ к DatePicker
из которого вы извлекли скин (например, сохранив его как переменную).
DatePicker datePicker = new DatePicker(LocalDate.now());
DatePickerSkin datePickerSkin = new DatePickerSkin(datePicker);
Node popupContent = datePickerSkin.getPopupContent();
//[...]
LocalDate selectedDate = datePicker.getValue();
Вы также можете прослушать изменения значения, добавив ChangeListener
к связанному имуществу:
datePicker.valueProperty().addListener(new ChangeListener<LocalDate>() {
@Override
public void changed(ObservableValue<? extends LocalDate> observable, LocalDate oldValue, LocalDate newValue) {
System.out.println("New Value: " + newValue);
}
});
//Or using neat lambda
datePicker.valueProperty().addListener((observable, oldValue, newValue) -> {
System.out.println("New Value: " + newValue);
});
Чтобы удалить панель "месяц-год", используйте:
DatePickerSkin datePickerSkin = new DatePickerSkin(date_picker);
Node popupContent = datePickerSkin.getPopupContent();
((DatePickerContent) popupContent).getChildren().remove(popupContent.lookup(".month-year-pane"));