JavaFX 从 DatePicker 中提取日历弹出窗口/仅显示弹出窗口

Posted

技术标签:

【中文标题】JavaFX 从 DatePicker 中提取日历弹出窗口/仅显示弹出窗口【英文标题】:JavaFX extract calendar-popup from DatePicker / only show popup 【发布时间】:2016-04-13 10:14:40 【问题描述】:

我正在尝试为 JavaFX 应用程序构建 CalendarView,仅显示日期(无需选择)。由于DatePicker 类有一个不错的日历弹出窗口,我想我可能会尝试提取它,以便我已经涵盖了所有样式问题。

那么有没有一种简单的方法来提取 DatePicker 日历弹出窗口并将其插入到新的 CalendarView 中?

我已经查看了 ComboBoxBase 类中的 show() 方法,以了解触​​发弹出窗口时究竟会发生什么,但我不得不承认我无法真正理解它。

或者,我可以考虑简单地编辑 DatePicker,使只有弹出窗口始终显示,而编辑器-TextField 和按钮组件总是隐藏,但我还是不知道如何在不隐藏的情况下做到这一点弹出窗口也是如此。此外,我可能需要获取弹出窗口的边界以在此替代方法中适当地管理高度和宽度,这似乎又不是那么容易。

【问题讨论】:

从头开始构建它可能会容易得多。 【参考方案1】:

您可以从 DatePickerSkin 中获取 DatePicker 的弹出内容。有关实现,请参阅此演示:

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 是公共 API 的一部分,不再需要使用封闭的 com.sun.[...] 实现。 (见JavaDoc)

另外,as mentioned in the comments,要获取所选值,您必须访问从中提取皮肤的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);
);

【讨论】:

从 JavaFX 8 开始,请注意 DatePickerSkin 不是公共 API 类。 (这将是一个公共 API class in JavaFX 9,尽管包名称会发生​​变化,并且可能是 API。)pretty straightforward 可以使用您需要的任何 API 直接实现它(并省略您不需要的)。跨度> @Modus Tollens 很抱歉这个愚蠢的问题,但是如何将“eventlistener”添加到该日历中,以便我可以检索被点击的那一天......? (来自android和javafx新手所以有点困惑):S @pb4now 将 DatePicker 保存在一个变量中,比如“myDatePicker”。然后你可以阅读“myDatePicker.getValue()”【参考方案2】:

要删除“月-年-窗格”,请使用:

DatePickerSkin datePickerSkin = new DatePickerSkin(date_picker);
Node popupContent = datePickerSkin.getPopupContent();
((DatePickerContent) popupContent).getChildren().remove(popupContent.lookup(".month-year-pane"));

【讨论】:

以上是关于JavaFX 从 DatePicker 中提取日历弹出窗口/仅显示弹出窗口的主要内容,如果未能解决你的问题,请参考以下文章

jquery datepicker 默认日期

即使从日历中选择日期,如何保持 mat-datepicker 日历打开?

特定格式的 JavaFX DatePicker getValue

页面上的多个更新面板从文本框中删除 JavaScript Datepicker 日历

DatePicker 的值在 Javafx 中 Tableview 的行中不断重置

JavaFX:setDisable(true)DatePicker问题