JavaFX 从 DatePicker 中提取日历弹出窗口/只显示弹出窗口
JavaFX extract calendar-popup from DatePicker / only show popup
我正在尝试为 JavaFX 应用程序构建 CalendarView,以仅显示日期(无需选择)。由于 DatePicker
class 有一个漂亮的日历弹出窗口,我想我可能会尝试提取它以便我已经涵盖了所有样式问题。
那么有没有一种简单的方法可以提取 DatePicker 日历弹出窗口并将其插入到新的 CalendarView 中?
我已经查看了 ComboBoxBase
class 中的 show()
方法,以查看触发弹出窗口时究竟发生了什么,但我不得不承认我无法真正理解绕过它。
或者,我可以考虑简单地编辑 DatePicker,使编辑器-TextField 和按钮组件始终隐藏,只有弹出窗口始终显示,但我还是无法完全弄清楚如何做到这一点隐藏弹出窗口。此外,我可能需要获取弹出窗口的边界以在此替代方案中适当地管理高度和宽度,这似乎又不是那么容易。
您可以从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
是 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
来收听 value-changes:
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);
});
要删除 "month-year-pane" 使用:
DatePickerSkin datePickerSkin = new DatePickerSkin(date_picker);
Node popupContent = datePickerSkin.getPopupContent();
((DatePickerContent) popupContent).getChildren().remove(popupContent.lookup(".month-year-pane"));
我正在尝试为 JavaFX 应用程序构建 CalendarView,以仅显示日期(无需选择)。由于 DatePicker
class 有一个漂亮的日历弹出窗口,我想我可能会尝试提取它以便我已经涵盖了所有样式问题。
那么有没有一种简单的方法可以提取 DatePicker 日历弹出窗口并将其插入到新的 CalendarView 中?
我已经查看了 ComboBoxBase
class 中的 show()
方法,以查看触发弹出窗口时究竟发生了什么,但我不得不承认我无法真正理解绕过它。
或者,我可以考虑简单地编辑 DatePicker,使编辑器-TextField 和按钮组件始终隐藏,只有弹出窗口始终显示,但我还是无法完全弄清楚如何做到这一点隐藏弹出窗口。此外,我可能需要获取弹出窗口的边界以在此替代方案中适当地管理高度和宽度,这似乎又不是那么容易。
您可以从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
是 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
来收听 value-changes:
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);
});
要删除 "month-year-pane" 使用:
DatePickerSkin datePickerSkin = new DatePickerSkin(date_picker);
Node popupContent = datePickerSkin.getPopupContent();
((DatePickerContent) popupContent).getChildren().remove(popupContent.lookup(".month-year-pane"));