是否有任何日期和时间选择器可用于javaFx?

我是Java的新手,我已经开始使用javaFx在java中开发应用程序。 搜索了很多,但无法在javaFx中找到任何日期和时间选择器。 即使我尝试JFxtras,但它不工作。 顺便说一下,我使用javafx 2.2.3和java 7.任何帮助将不胜感激。

这里是上面的DateTimePicker控件的Java版本,略有改进。

此代码现在是TornadoFX Controls的一部分,您可以在GitHub Repo中查看最新版本的DateTimePicker.java 。 这个控件在Maven Central中也可以在这些坐标下使用:

<dependency> <groupId>no.tornado</groupId> <artifactId>tornadofx-controls</artifactId> <version>1.0.3</version> </dependency> 

现在执行:

 import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.scene.control.DatePicker; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.util.StringConverter; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; /** * A DateTimePicker with configurable datetime format where both date and time can be changed * via the text field and the date can additionally be changed via the JavaFX default date picker. */ @SuppressWarnings("unused") public class DateTimePicker extends DatePicker { public static final String DefaultFormat = "yyyy-MM-dd HH:mm"; private DateTimeFormatter formatter; private ObjectProperty<LocalDateTime> dateTimeValue = new SimpleObjectProperty<>(LocalDateTime.now()); private ObjectProperty<String> format = new SimpleObjectProperty<String>() { public void set(String newValue) { super.set(newValue); formatter = DateTimeFormatter.ofPattern(newValue); } }; public DateTimePicker() { getStyleClass().add("datetime-picker"); setFormat(DefaultFormat); setConverter(new InternalConverter()); // Syncronize changes to the underlying date value back to the dateTimeValue valueProperty().addListener((observable, oldValue, newValue) -> { if (newValue == null) { dateTimeValue.set(null); } else { if (dateTimeValue.get() == null) { dateTimeValue.set(LocalDateTime.of(newValue, LocalTime.now())); } else { LocalTime time = dateTimeValue.get().toLocalTime(); dateTimeValue.set(LocalDateTime.of(newValue, time)); } } }); // Syncronize changes to dateTimeValue back to the underlying date value dateTimeValue.addListener((observable, oldValue, newValue) -> { setValue(newValue == null ? null : newValue.toLocalDate()); }); // Persist changes onblur getEditor().focusedProperty().addListener((observable, oldValue, newValue) -> { if (!newValue) simulateEnterPressed(); }); } private void simulateEnterPressed() { getEditor().fireEvent(new KeyEvent(getEditor(), getEditor(), KeyEvent.KEY_PRESSED, null, null, KeyCode.ENTER, false, false, false, false)); } public LocalDateTime getDateTimeValue() { return dateTimeValue.get(); } public void setDateTimeValue(LocalDateTime dateTimeValue) { this.dateTimeValue.set(dateTimeValue); } public ObjectProperty<LocalDateTime> dateTimeValueProperty() { return dateTimeValue; } public String getFormat() { return format.get(); } public ObjectProperty<String> formatProperty() { return format; } public void setFormat(String format) { this.format.set(format); } class InternalConverter extends StringConverter<LocalDate> { public String toString(LocalDate object) { LocalDateTime value = getDateTimeValue(); return (value != null) ? value.format(formatter) : ""; } public LocalDate fromString(String value) { if (value == null) { dateTimeValue.set(null); return null; } dateTimeValue.set(LocalDateTime.parse(value, formatter)); return dateTimeValue.get().toLocalDate(); } } } 

dateTimeValue属性包含随时间变化的值,而valueProperty包含日期值。

我还没有为这个组件添加测试,所以实现可能会改变,请检查GitHub的最新版本。

JFXtras项目有一个适用于JavaFX 2.2的工作版本。 在2.2分支下的回购中查找CalendarPickerCalendarTimePicker …。

您可以通过从jfxtras.org下载最新版本( 2.2-r6-SNAPSHOT )来进行测试 。

这个简短的代码将创建一个日期和时间选择的日历:

 @Override public void start(Stage primaryStage) { CalendarPicker dateTime = new CalendarPicker(); dateTime.withCalendar(Calendar.getInstance()); dateTime.withShowTime(Boolean.TRUE); dateTime.withLocale(Locale.ENGLISH); dateTime.calendarProperty().addListener(new ChangeListener<Calendar>() { @Override public void changed(ObservableValue<? extends Calendar> ov, Calendar t, Calendar t1) { System.out.println("Selected date: "+t1.getTime().toString()); } }); StackPane root = new StackPane(); root.getChildren().add(dateTime); Scene scene = new Scene(root, 300, 250); primaryStage.setTitle("Date & Time from JFXtras 2.2"); primaryStage.setScene(scene); primaryStage.show(); } 

日期和时间

我发现通过键盘输入时间最方便,而不是用滑块改变它。 将包含的DatePicker扩展为如下所示很容易:

DateTimePicker为JavaFX 8

我也发现DatePicker没有提交TextField onblur中的编辑值,所以下面的代码也修复了这个问题。

该代码片段是用Kotlin编写的,可以通过IntelliJ IDEA轻松地将其转换为Java代码:

 import javafx.beans.property.SimpleObjectProperty import javafx.scene.control.DatePicker import javafx.scene.input.KeyCode import javafx.scene.input.KeyEvent import javafx.scene.input.MouseEvent import javafx.util.StringConverter import java.time.LocalDate import java.time.LocalDateTime import java.time.LocalTime import java.time.format.DateTimeFormatter class DateTimePicker(val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")) : DatePicker() { private var dateTimeValue = SimpleObjectProperty<LocalDateTime>(LocalDateTime.now()) init { converter = object : StringConverter<LocalDate>() { override fun toString(value: LocalDate?): String { return if (dateTimeValue.get() != null) dateTimeValue.get().format(formatter) else "" } override fun fromString(value: String?): LocalDate? { if (value == null) { dateTimeValue.set(null) return null } dateTimeValue.set(LocalDateTime.parse(value, formatter)) return dateTimeValue.get().toLocalDate() } } // Syncronize changes to the underlying date value back to the dateTimeValue valueProperty().addListener { observable, old, new -> if (new == null) { dateTimeValue.set(null) } else { if (dateTimeValue.get() == null) { dateTimeValue.set(LocalDateTime.of(new, LocalTime.now())) } else { val time = dateTimeValue.get().toLocalTime() dateTimeValue.set(LocalDateTime.of(new, time)) } } } // Syncronize changes to dateTimeValue back to the underlying date value dateTimeValue.addListener { observable, old, new -> valueProperty().set(new?.toLocalDate()) } // Persist changes onblur editor.focusedProperty().addListener { observable, old, new -> if (!new) simulateEnterPressed() } } private fun simulateEnterPressed() = editor.fireEvent(KeyEvent(editor, editor, KeyEvent.KEY_PRESSED, null, null, KeyCode.ENTER, false, false, false, false)) fun dateTimeValueProperty() = dateTimeValue; } 

将LocalDateTime属性绑定到dateTimeValueProperty。

稍微“改进”(至少对于我的需要)版本,与NullableTimeStamp …一起工作,以便能够,以及为空(为了方便与MySQL)…

不知道如果这可以帮助任何人,但在这里它是:

NullableTimeStamp:

 public class NullableTimestamp extends Timestamp { public NullableTimestamp() { super(0L); } public NullableTimestamp(long value) { super(value); } @Override public String toString() { return this.getTime() > 0L ? super.toString() : ""; } public static NullableTimestamp valueOf(LocalDateTime localDateTime) { return new NullableTimestamp(Timestamp.valueOf(localDateTime).getTime()); } } 

和DateTimePicker:

 public class DateTimePicker extends DatePicker { public static final String DefaultFormat = "yyyy-MM-dd HH:mm"; private DateTimeFormatter formatter; private ObjectProperty<LocalDateTime> dateTimeValue = new SimpleObjectProperty<>(LocalDateTime.now()); private ObjectProperty<String> format = new SimpleObjectProperty<String>() { public void set(String newValue) { super.set(newValue); formatter = DateTimeFormatter.ofPattern(newValue); } }; public DateTimePicker() { getStyleClass().add("datetime-picker"); setFormat(DefaultFormat); setConverter(new InternalConverter()); // Syncronize changes to the underlying date value back to the dateTimeValue valueProperty().addListener((observable, oldValue, newValue) -> { if (newValue == null) { dateTimeValue.set(null); } else { if (dateTimeValue.get() == null) { dateTimeValue.set(LocalDateTime.of(newValue, LocalTime.now())); } else { LocalTime time = dateTimeValue.get().toLocalTime(); dateTimeValue.set(LocalDateTime.of(newValue, time)); } } }); // Syncronize changes to dateTimeValue back to the underlying date value dateTimeValue.addListener((observable, oldValue, newValue) -> { setValue(newValue == null ? null : newValue.toLocalDate()); }); // Persist changes onblur getEditor().focusedProperty().addListener((observable, oldValue, newValue) -> { if (!newValue) simulateEnterPressed(); }); } private void simulateEnterPressed() { getEditor().fireEvent(new KeyEvent(getEditor(), getEditor(), KeyEvent.KEY_PRESSED, null, null, KeyCode.ENTER, false, false, false, false)); } public LocalDateTime getDateTimeValue() { return dateTimeValue.get(); } public void setDateTimeValue(LocalDateTime dateTimeValue) { if(dateTimeValue.isAfter(LocalDateTime.of(1971, 6, 30, 12, 00))) this.dateTimeValue.set(dateTimeValue); else this.dateTimeValue.set(null); } public ObjectProperty<LocalDateTime> dateTimeValueProperty() { return dateTimeValue; } public String getFormat() { return format.get(); } public ObjectProperty<String> formatProperty() { return format; } public void setFormat(String format) { this.format.set(format); } class InternalConverter extends StringConverter<LocalDate> { public String toString(LocalDate object) { LocalDateTime value = getDateTimeValue(); return (value != null) ? value.format(formatter) : ""; } public LocalDate fromString(String value) { if (value == null) { dateTimeValue.set(null); return null; } dateTimeValue.set(LocalDateTime.parse(value, formatter)); return dateTimeValue.get().toLocalDate(); } } } 

它基本上掩盖0L时间戳值,就像它是NULL …希望这可以帮助欢呼