JavaFX 从 DatePicker 中提取日历弹出窗口/仅显示弹出窗口
我正在尝试为 JavaFX 应用程序构建 CalendarView,仅显示日期(无需选择).由于 DatePicker
类有一个不错的日历弹出窗口,我想我可能会尝试提取它,以便我已经涵盖了所有样式问题.
I'm trying to build an CalendarView for an JavaFX application, to only display dates(no selecting required). Since the DatePicker
class has a nice calendar popup I thought I might try to extract it so that I already have all the style-questions covered.
那么有没有一种简单的方法来提取 DatePicker 日历弹出窗口并将其插入到新的 CalendarView 中?
So is there an easy way to extract the DatePicker calendar popup and insert it into a new CalendarView?
我已经查看了 ComboBoxBase
类中的 show()
方法,以了解触发弹出窗口时究竟发生了什么,但我不得不承认我真的不能想一想.
I already looked at the show()
method from the ComboBoxBase
class to see what exactly happens when the popup is triggered but I have to admit I couldn't really get my head around it.
或者,我可以考虑简单地编辑 DatePicker 以一种只有弹出窗口始终显示的方式,而 editor-TextField 和按钮组件总是隐藏,但我还是不知道如何在不隐藏的情况下做到这一点弹出窗口也是如此.此外,我可能需要获得弹出窗口的边界以在此替代方法中适当地管理高度和宽度,这似乎又不是那么容易.
Alternatively I could think about simply edit the DatePicker in a way that only the popup shows all the time with the editor-TextField and button component always hiding, but again I couldn't quite figure out how to do that without hiding the popup as well. Also I would propably need to get the bounds of the popup to approptiately manage height and width in this alternativw, which again seems to be not that easy.
推荐答案
您可以从 DatePickerSkin 中获取 DatePicker 的弹出内容.有关实现,请参阅此演示:
You can get the popup content of a DatePicker from a DatePickerSkin. See this demo for an implementation:
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);
}
}
如果不需要顶栏,可以查找并隐藏.
If the top bar is not needed, you can look it up and hide it.
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 of JDK 9 DatePickerSkin
is part of the Public API and using the closed com.sun.[...]
implementation is no longer needed. (See JavaDoc)
另外,如评论中所述,要获取所选值,您必须访问从中提取皮肤的 DatePicker
(例如,将其保存为变量).
Also, as mentioned in the comments, to get the selected value you have to access the DatePicker
from which you extracted the skin (by saving it as an variable for example).
DatePicker datePicker = new DatePicker(LocalDate.now());
DatePickerSkin datePickerSkin = new DatePickerSkin(datePicker);
Node popupContent = datePickerSkin.getPopupContent();
//[...]
LocalDate selectedDate = datePicker.getValue();
您还可以通过向关联属性添加 ChangeListener
来监听值更改:
You can also listen to value-changes by adding a ChangeListener
to the associated property:
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);
});
相关文章