1. Обзор
В этой статье показан пример приложения Java SE 8 Swing, использующего DatePicker
управления JavaFX 8 DatePicker
.
DatePicker
управления DatePicker
позволяет пользователю вводить дату в виде текста или выбирать дату во всплывающем календаре. В этом примере используется Swing JFrame
с элементами управления FX. Для встраивания содержимого FX в приложение javafx.embed.swing
пакет javafx.embed.swing
предоставляет класс JFXPanel
.
Приложение берет введенную дату из средства выбора даты и проверяет, находится ли оно в выбранном пользователем диапазоне дат (от и до даты) из двух средств выбора даты. Проверка даты выбора даты включает в себя:
- Дата от меньше даты
- Даты не из будущего
- Дата ввода находится в пределах от и до даты (включая)
Недопустимые или действительные сообщения отображаются в диалоговых окнах FX Alert
.
На следующих двух FXPanel
экрана показано приложение с JFrame
и встроенными элементами управления FX ( FXPanel
с DatePicker
, DatePicker
и Button
) и DatePicker
календарем DatePicker
соответственно.
1.1. Исходный код
Исходный код для этого примера FXDatePickerInSwingExample.java
доступен для загрузки по ссылке, приведенной в конце этой статьи. Обратите внимание, что Java SE 8 требуется для компиляции и запуска кода. Java SE 8 включает в себя JavaFX 8.
2. Описание приложения
Приложение Java Swing FXDatePickerInSwingExample
запускается из метода main()
программы Java SE в потоке диспетчеризации событий следующим образом:
1
2
3
|
SwingUtilities.invokeLater(() -> { new FXDatePickerInSwingExample().initAndShowGUI(); }); |
Метод initAndShowGUI()
отображает Swing JFrame
со встроенными в него элементами управления JavaFX. Следующий фрагмент кода показывает конструкцию JFrame
:
1
2
3
4
|
JFrame frame = new JFrame( "JavaFX DatePicker in Swing App" ); JFXPanel fxPanel = new JFXPanel(); frame.add(fxPanel); frame.setVisible( true ); |
javafx.embed.swing.JFXPanel
является компонентом для встраивания содержимого JavaFX в приложения Swing и обеспечивает совместимость JavaFX и Swing. JFXPanel
расширяет JFXPanel
javax.swing.JComponent
. Отображаемый контент указывается с помощью JFXPanel
setScene()
который принимает экземпляр javafx.scene.Scene
. Этот метод вызывается в потоке диспетчеризации событий приложения FX следующим образом:
1
2
3
|
Platform.runLater(() -> { fxPanel.setScene(createScene()); }); |
Метод createScene()
возвращает экземпляр Scene
с элементами управления FX. Скриншоты, показанные выше, имеют законченный графический интерфейс. В следующем фрагменте кода показан метод createScene()
с фрагментами кода:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
private Scene createScene() { GridPane grid = new GridPane(); // Title Label title1 = new Label( "Enter and check if the input date is" ); Label title2 = new Label( "within the selected date range." ); VBox titleVb = new VBox(); titleVb.setAlignment(Pos.CENTER); titleVb.getChildren().addAll(title1, title2); // Input date picker Label inPickLabel = new Label( "Input date:" ); inPicker = new DatePicker(); inPicker.setPromptText(pattern); DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); StringConverter converter = new LocalDateStringConverter(formatter, null ); inPicker.setConverter(converter); grid.add(inPickLabel, 0 , 0 ); grid.add(inPicker, 1 , 0 ); // From and to date pickers Label pickLabel1 = new Label( "From date:" ); fmPicker = new DatePicker(LocalDate.now()); fmPicker.setEditable( false ); grid.add(pickLabel1, 0 , 1 ); grid.add(fmPicker, 1 , 1 ); ... // Button ... // Vbox and scene VBox vbox = new VBox( 20 ); vbox.setPadding( new Insets( 15 , 15 , 15 , 15 )); vbox.getChildren().addAll(titleVb, grid, btnHb); return new Scene(vbox); } |
2.1. Элемент управления DatePicker
javafx.scene.control.DatePicker
управления javafx.scene.control.DatePicker
позволяет пользователю вводить дату в виде текста или выбирать дату во всплывающем календаре. Свойство DatePicker
представляет LocalDate
выбранный LocalDate
. Это свойство может использоваться с конструктором, а также имеет методы getValue()
и setValue()
.
Следующий фрагмент кода создает объект выбора даты и устанавливает его значение на сегодняшнюю дату: DatePicker picker = new DatePicker(LocalDate.now());
2.2. Проверка даты
В этом приложении есть три сборщика даты. Все они настроены на сбор действительных дат:
- Значения даты не могут быть больше, чем сегодня.
- Дата начала никогда не может быть после даты.
Для выполнения этих ограничений используется dayCellFactoryProperty
DatePicker
. Можно настроить собственную фабрику ячеек для настройки отдельных ячеек дня во всплывающем окне выбора даты. У средства выбора даты есть метод для установки фабрики пользовательских ячеек: setDayCellFactory()
.
Эти API используются для создания собственной фабрики ячеек: класс DateCell
используется DateCell
даты для визуализации отдельных ячеек сетки в календарном месяце. Приложение может переопределить метод update
DateCell
чтобы изменить свойства каждой ячейки, такие как текст, цвет фона и т. Д.
В следующем фрагменте кода показан метод, который возвращает пользовательский dayCellFactory
. Обратите внимание, что этот единственный метод возвращает фабрику ячеек для трех сборщиков дат.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
private Callback getCustomDateCellFactory(DateParameterType dateParamType) { Callback dayCellFactory = new Callback() { @Override public DateCell call(DatePicker datePicker) { return new DateCell() { @Override public void updateItem(LocalDate select, boolean b) { super .updateItem(select, empty); // Date cannot be after today. // This applies for all the date pickers. if (select.isAfter(LocalDate.now())) { setDisable( true ); return ; } // From-date cannot be greater than to-date. if ((dateParamType == DateParameterType.FROM_DATE) && (select.isAfter(toPicker.getValue()))) { setDisable( true ); } // To-date cannot be less than from-date, // and cannot be greater than today. if (dateParamType == DateParameterType.TO_DATE) { if ((select.isBefore(fmPicker.getValue())) || (select.isAfter(LocalDate.now()))) { setDisable( true ); } } ... }; return dayCellFactory; } |
Этот пользовательский dayCellFactory
применяется к средствам dayCellFactory
даты в createScene()
следующим образом:
1
2
3
|
inPicker.setDayCellFactory(getCustomDateCellFactory( null )); fmPicker.setDayCellFactory(getCustomDateCellFactory(DateParameterType.FROM_DATE)); toPicker.setDayCellFactory(getCustomDateCellFactory(DateParameterType.TO_DATE)); |
Метод getCustomDateCellFactory()
приложения возвращает фабрику пользовательских ячеек, getCustomDateCellFactory()
выше. Параметр метода DateParameterType
enum
идентифицирует DateParameterType
даты, для которого применяется фабрика ячеек. Например, средство выбора даты требует даты выбора текущей даты, чтобы получить ячейки, которые должны быть отключены; поэтому DateParameterType.FROM
используется для идентификации соответствующего фрагмента кода (см. следующий фрагмент кода).
1
2
3
4
5
|
// From-date cannot be greater than to-date. if ((dateParamType == DateParameterType.FROM_DATE) && (select.isAfter(toPicker.getValue()))) { setDisable( true ); } |
2,3. Пользовательский конвертер для ввода даты
По умолчанию средство выбора даты показывает строку даты в шаблоне (например, дд / мм / гггг) в соответствии с конвертером по умолчанию. Это можно переопределить, предоставив специальный преобразователь в DatePicker
setConverter()
. Выбор даты ввода принимает и показывает дату в формате, отличном (dd-MMM-yy) от формата по умолчанию, используя пользовательский конвертер. Следующее примечание показывает использование пользовательского конвертера.
Эти API используются для создания пользовательского конвертера в этом примере:
-
javafx.util.StringConverter
: этот абстрактный класс определяет поведение преобразования между строками и объектами. -
javafx.util.converter.LocalDateStringConverter
: этот класс является реализациейStringConverter
для значенийLocalDate
. -
java.time.format.DateTimeFormatter
: это средство форматирования для печати и анализа объектов даты и времени.
Создайте StringConverter
для значений LocalDate
используя предоставленные LocalDate
форматирования и анализатор. Форматтер используется для преобразования даты в форматированную строку с использованием указанного шаблона. Обратите внимание, что парсер указан как ноль. Этот конвертер применяется к входному DatePicker
dd-MMM-yy
. При выборе из всплывающего окна дата отображается в формате dd-MMM-yy
с помощью конвертера.
Следующий фрагмент кода показывает создание и использование конвертера:
1
2
3
4
|
String pattern = "dd-MMM-yy" ; DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); StringConverter converter = new LocalDateStringConverter(formatter, null ); picker.setConverter(converter); |
2,4. LocalDate
Java.time.LocalDate
— это дата в календарной системе ISO-8601 (современная гражданская календарная система, используемая сегодня в большинстве стран мира), например, 2007-12-03. В этом классе не хранится информация о времени или часовом поясе. Экземпляр может быть создан из года, месяца и дня с использованием статического метода LocalDate.of(int year, int month, int dayOfMonth)
.
Ниже приведены API, используемые в этом приложении:
-
LocalDate.now()
получает текущую дату из системных часов в часовом поясе по умолчанию. Это статический метод. -
isAfter(ChronoLocalDate localDate)
проверяет, находится ли эта дата после указанной даты. Это проверяет, представляет ли эта дата точку на местной временной шкале после другой даты.LocalDate
реализует интерфейсjava.time.chrono.ChronoLocalDate
. -
isBefore(ChronoLocalDate localDate)
проверяет,isBefore(ChronoLocalDate localDate)
ли эта дата указанной дате. -
isEqual(ChronoLocalDate localDate)
проверяет, равна ли эта дата указанной дате.
Следующая процедура используется в примере, чтобы проверить, находится ли введенная дата в выбранном диапазоне дат. Входные данные, а также выбранные даты и даты получены из DatePicker
управления DatePicker
. DatePicker
getValue()
LocalDate
возвращает объект LocalDate
.
01
02
03
04
05
06
07
08
09
10
11
|
private boolean validDate(LocalDate start, LocalDate end, LocalDate input) { if ((input.isEqual(start)) || (input.isEqual(end))) { return true ; } else if ((input.isAfter(start)) && (input.isBefore(end))) { return true ; } else { return false ; } } |
3. Оповещения
Это ссылка на статью, описывающую диалоги javafx.scene.control.Alert
используемые в этом примере.
4. Пример использования
Java Swing не имеет компонента выбора даты. Используя технику, показанную в этом примере, приложение Swing может использовать DatePicker
управления DatePicker
FX в DatePicker
Swing JFrame
. Например, этот JFrame
может быть диалоговым окном функции «Поиск по дате», где можно выбрать диапазон дат, а входные данные (например, коллекция счетов) можно искать по их датам в пределах выбранного диапазона дат.
Окно приложения Swing может открыть это диалоговое окно JFrame
в качестве немодального окна, когда пользователь нажимает кнопку «Поиск по дате» actionPerformed()
метод actionPerformed()
кнопки actionPerformed()
создает экземпляр этого диалога «Поиск по дате»).
5. Скачать исходный код
Это был пример JavaFX 8 DatePicker in Swing Application
*