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"));
Другие вопросы по тегам