Skip to content

Commit da5bd37

Browse files
Marius Hanlaghaisas
Marius Hanl
authored andcommitted
8277756: DatePicker listener might not be added when using second constructor
Reviewed-by: aghaisas
1 parent 864792d commit da5bd37

File tree

2 files changed

+97
-22
lines changed

2 files changed

+97
-22
lines changed

modules/javafx.controls/src/main/java/javafx/scene/control/DatePicker.java

+21-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -106,7 +106,15 @@ public class DatePicker extends ComboBoxBase<LocalDate> {
106106
*/
107107
public DatePicker() {
108108
this(null);
109+
}
109110

111+
/**
112+
* Creates a DatePicker instance and sets the
113+
* {@link #valueProperty() value} to the given date.
114+
*
115+
* @param localDate to be set as the currently selected date in the DatePicker. Can be null.
116+
*/
117+
public DatePicker(LocalDate localDate) {
110118
valueProperty().addListener(observable -> {
111119
LocalDate date = getValue();
112120
Chronology chrono = getChronology();
@@ -115,7 +123,7 @@ public DatePicker() {
115123
lastValidDate = date;
116124
} else {
117125
System.err.println("Restoring value to " +
118-
((lastValidDate == null) ? "null" : getConverter().toString(lastValidDate)));
126+
((lastValidDate == null) ? "null" : getConverter().toString(lastValidDate)));
119127
setValue(lastValidDate);
120128
}
121129
});
@@ -132,6 +140,17 @@ public DatePicker() {
132140
setChronology(lastValidChronology);
133141
}
134142
});
143+
144+
setValue(localDate);
145+
getStyleClass().add(DEFAULT_STYLE_CLASS);
146+
setAccessibleRole(AccessibleRole.DATE_PICKER);
147+
setEditable(true);
148+
149+
focusedProperty().addListener(o -> {
150+
if (!isFocused()) {
151+
commitValue();
152+
}
153+
});
135154
}
136155

137156
private boolean validateDate(Chronology chrono, LocalDate date) {
@@ -146,25 +165,6 @@ private boolean validateDate(Chronology chrono, LocalDate date) {
146165
}
147166
}
148167

149-
/**
150-
* Creates a DatePicker instance and sets the
151-
* {@link #valueProperty() value} to the given date.
152-
*
153-
* @param localDate to be set as the currently selected date in the DatePicker. Can be null.
154-
*/
155-
public DatePicker(LocalDate localDate) {
156-
setValue(localDate);
157-
getStyleClass().add(DEFAULT_STYLE_CLASS);
158-
setAccessibleRole(AccessibleRole.DATE_PICKER);
159-
setEditable(true);
160-
161-
focusedProperty().addListener(o -> {
162-
if (!isFocused()) {
163-
commitValue();
164-
}
165-
});
166-
}
167-
168168

169169
/* *************************************************************************
170170
* *

modules/javafx.controls/src/test/java/test/javafx/scene/control/DatePickerTest.java

+76-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,12 @@
2525

2626
package test.javafx.scene.control;
2727

28+
import java.time.DateTimeException;
2829
import java.time.LocalDate;
2930
import java.time.chrono.*;
31+
import java.time.temporal.ChronoField;
32+
import java.time.temporal.TemporalAccessor;
33+
import java.time.temporal.ValueRange;
3034
import java.util.*;
3135

3236
import javafx.scene.control.Button;
@@ -620,6 +624,30 @@ public Node getDisplayNode() {
620624
sl.dispose();
621625
}
622626

627+
@Test
628+
public void testInvalidChronologyIsRestored() {
629+
datePicker = new DatePicker(LocalDate.of(1998, 1, 23));
630+
datePicker.setChronology(IsoChronology.INSTANCE);
631+
632+
assertEquals(IsoChronology.INSTANCE, datePicker.getChronology());
633+
634+
// This should restore the old set chronology (Iso) as the chronology is invalid.
635+
datePicker.setChronology(new InvalidChronology());
636+
assertEquals(IsoChronology.INSTANCE, datePicker.getChronology());
637+
}
638+
639+
@Test
640+
public void testInvalidValueIsRestored() {
641+
datePicker = new DatePicker(null);
642+
assertNull(datePicker.getValue());
643+
644+
datePicker.setChronology(new InvalidChronology());
645+
// This should restore the old set value (null) as the chronology is invalid.
646+
datePicker.setValue(LocalDate.of(1998, 1, 23));
647+
648+
assertNull(datePicker.getValue());
649+
}
650+
623651
@Test
624652
public void testCommitValue() {
625653
datePicker.setEditable(true);
@@ -709,4 +737,51 @@ public void testFocusLost() {
709737
stageLoader.dispose();
710738
}
711739

740+
private class InvalidChronology extends AbstractChronology {
741+
@Override
742+
public String getId() {
743+
return null;
744+
}
745+
@Override
746+
public String getCalendarType() {
747+
return null;
748+
}
749+
@Override
750+
public ChronoLocalDate date(int prolepticYear, int month, int dayOfMonth) {
751+
return null;
752+
}
753+
@Override
754+
public ChronoLocalDate dateYearDay(int prolepticYear, int dayOfYear) {
755+
return null;
756+
}
757+
@Override
758+
public ChronoLocalDate dateEpochDay(long epochDay) {
759+
return null;
760+
}
761+
@Override
762+
public ChronoLocalDate date(TemporalAccessor temporal) {
763+
throw new DateTimeException("Invalid");
764+
}
765+
@Override
766+
public boolean isLeapYear(long prolepticYear) {
767+
return false;
768+
}
769+
@Override
770+
public int prolepticYear(Era era, int yearOfEra) {
771+
return 0;
772+
}
773+
@Override
774+
public Era eraOf(int eraValue) {
775+
return null;
776+
}
777+
@Override
778+
public List<Era> eras() {
779+
return null;
780+
}
781+
@Override
782+
public ValueRange range(ChronoField field) {
783+
return null;
784+
}
785+
}
786+
712787
}

0 commit comments

Comments
 (0)