Skip to content

Commit 01bf156

Browse files
committed
DatePickers: Actually follow the interface specification
Signed-off-by: Taylor Smock <[email protected]>
1 parent 3fd429d commit 01bf156

File tree

6 files changed

+70
-33
lines changed

6 files changed

+70
-33
lines changed

src/main/java/org/openstreetmap/josm/plugins/datepicker/IDatePicker.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ static IDatePicker<JComponent> getNewDatePicker() {
7575
Logging.error(e);
7676
}
7777
// Fall back to basic text entry
78-
IDatePicker<?> rDatePicker = new DatePickerSwing();
79-
return (IDatePicker<JComponent>) rDatePicker;
78+
return (IDatePicker<JComponent>) ((IDatePicker<?>) new DatePickerSwing());
8079
}
8180
}

src/main/java/org/openstreetmap/josm/plugins/datepicker/impl/DatePickerJDatePicker.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
import java.util.Properties;
99
import java.util.function.Consumer;
1010

11+
import javax.annotation.Nonnull;
12+
1113
import org.jdatepicker.impl.DateComponentFormatter;
1214
import org.jdatepicker.impl.JDatePanelImpl;
1315
import org.jdatepicker.impl.JDatePickerImpl;
1416
import org.jdatepicker.impl.UtilCalendarModel;
15-
1617
import org.openstreetmap.josm.plugins.datepicker.IDatePicker;
1718

1819
/**
@@ -42,23 +43,26 @@ public DatePickerJDatePicker() {
4243
}
4344

4445
@Override
45-
public void setInstant(Instant date) {
46-
if (date != null) {
46+
public void setInstant(@Nonnull Instant date) {
47+
if (Instant.MIN.isBefore(date)) {
4748
Calendar cal = Calendar.getInstance();
4849
cal.setTimeInMillis(date.toEpochMilli());
4950
model.setValue(cal);
50-
} else
51+
} else {
5152
reset();
53+
}
5254
}
5355

56+
@Nonnull
5457
@Override
5558
public Instant getInstant() {
5659
Calendar value = model.getValue();
5760
if (value == null)
58-
return null;
61+
return Instant.MIN;
5962
return value.toInstant();
6063
}
6164

65+
@Nonnull
6266
@Override
6367
public JDatePickerImpl getComponent() {
6468
return this.datePicker;
@@ -71,7 +75,7 @@ public void reset() {
7175
}
7276

7377
@Override
74-
public void addEventHandler(Consumer<IDatePicker<?>> function) {
78+
public void addEventHandler(@Nonnull Consumer<IDatePicker<?>> function) {
7579
this.datePicker.addActionListener(action -> function.accept(this));
7680
}
7781

src/main/java/org/openstreetmap/josm/plugins/datepicker/impl/DatePickerSwing.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import java.time.format.DateTimeFormatter;
1010
import java.util.function.Consumer;
1111

12+
import javax.annotation.Nonnull;
13+
1214
import org.openstreetmap.josm.gui.widgets.DisableShortcutsOnFocusGainedTextField;
1315
import org.openstreetmap.josm.gui.widgets.JosmTextField;
1416
import org.openstreetmap.josm.plugins.datepicker.IDatePicker;
@@ -29,21 +31,23 @@ public DatePickerSwing() {
2931
}
3032

3133
@Override
32-
public void setInstant(Instant date) {
34+
public void setInstant(@Nonnull Instant date) {
3335
this.date = date;
34-
if (date != null) {
36+
if (Instant.MIN.isBefore(date)) {
3537
this.component
3638
.setText(DateTimeFormatter.ISO_DATE.format(ZonedDateTime.ofInstant(this.date, ZoneOffset.UTC)));
3739
} else {
3840
component.setText("");
3941
}
4042
}
4143

44+
@Nonnull
4245
@Override
4346
public Instant getInstant() {
4447
return this.date;
4548
}
4649

50+
@Nonnull
4751
@Override
4852
public JosmTextField getComponent() {
4953
return component;
@@ -55,7 +59,7 @@ public void reset() {
5559
}
5660

5761
@Override
58-
public void addEventHandler(Consumer<IDatePicker<?>> function) {
62+
public void addEventHandler(@Nonnull Consumer<IDatePicker<?>> function) {
5963
component.addFocusListener(new FocusListener() {
6064

6165
@Override
@@ -65,7 +69,7 @@ public void focusGained(FocusEvent e) {
6569

6670
@Override
6771
public void focusLost(FocusEvent e) {
68-
setInstant(null);
72+
setInstant(Instant.MIN);
6973
function.accept(DatePickerSwing.this);
7074
}
7175
});

src/main/java/org/openstreetmap/josm/plugins/mapillary/gui/dialog/MapillaryFilterDialog.java

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.stream.LongStream;
2929
import java.util.stream.Stream;
3030

31+
import javax.annotation.Nonnull;
3132
import javax.swing.AbstractAction;
3233
import javax.swing.JButton;
3334
import javax.swing.JCheckBox;
@@ -308,8 +309,10 @@ private void addTimeFilters(JPanel panel) {
308309
this.resetObjects.addListener(() -> spinnerModel.setValue(1));
309310

310311
this.resetObjects.addListener(() -> {
311-
if (endDate != null && startDate != null) {
312+
if (!endDate.getInstant().equals(Instant.MIN)) {
312313
endDate.reset();
314+
}
315+
if (!startDate.getInstant().equals(Instant.MIN)) {
313316
startDate.reset();
314317
}
315318
});
@@ -325,7 +328,9 @@ private void addTimeFilters(JPanel panel) {
325328
setFields.reset();
326329
}
327330

328-
private static Instant convertDateRangeBox(SpinnerNumberModel spinner, JComboBox<String> timeStep) {
331+
@Nonnull
332+
private static Instant convertDateRangeBox(@Nonnull SpinnerNumberModel spinner,
333+
@Nonnull JComboBox<String> timeStep) {
329334
if (timeStep.isEnabled()) {
330335
ZonedDateTime current = LocalDate.now(ZoneOffset.UTC).atStartOfDay(ZoneOffset.UTC);
331336
String type = (String) timeStep.getSelectedItem();
@@ -338,20 +343,21 @@ private static Instant convertDateRangeBox(SpinnerNumberModel spinner, JComboBox
338343
} else if (TIME_LIST[1].equals(type)) {
339344
difference[1] = start.intValue();
340345
difference[2] = (int) ((start.floatValue() - difference[1]) * 30);
341-
} else if (TIME_LIST[2].contentEquals(type)) {
346+
} else if (TIME_LIST[2].equals(type)) {
342347
difference[2] = start.intValue();
343348
}
344349
return current.minus(difference[0], ChronoUnit.YEARS).minus(difference[1], ChronoUnit.MONTHS)
345350
.minus(difference[2], ChronoUnit.DAYS).toInstant();
346351
}
347-
return null;
352+
return Instant.MIN;
348353
}
349354

350355
private static void updateDates(IDatePicker<?> startDate, IDatePicker<?> endDate, IDatePicker<?> modified) {
351356
Instant start = startDate.getInstant();
352357
Instant end = endDate.getInstant();
353-
if (start == null || end == null)
358+
if (Instant.MIN.equals(start) || Instant.MIN.equals(end)) {
354359
return;
360+
}
355361
if (startDate.equals(modified) && start.compareTo(end) > 0) {
356362
endDate.setInstant(start);
357363
} else if (endDate.equals(modified) && start.compareTo(end) > 0) {
@@ -365,11 +371,26 @@ private static void updateDates(IDatePicker<?> startDate, IDatePicker<?> endDate
365371
* @return the unique instance of the class.
366372
*/
367373
public static synchronized MapillaryFilterDialog getInstance() {
368-
if (instance == null)
369-
instance = new MapillaryFilterDialog();
374+
if (instance != null) {
375+
return instance;
376+
}
377+
synchronized (MapillaryFilterDialog.class) {
378+
if (instance == null) {
379+
instance = new MapillaryFilterDialog();
380+
}
381+
}
370382
return instance;
371383
}
372384

385+
/**
386+
* Check if the filter dialog has been created
387+
*
388+
* @return {@code true} if there is an already created instance
389+
*/
390+
public static boolean hasInstance() {
391+
return instance != null;
392+
}
393+
373394
/**
374395
* Resets the dialog to its default state.
375396
*/
@@ -471,8 +492,7 @@ public boolean test(INode img) {
471492
return true;
472493
}
473494
}
474-
if ((this.timeFilter && checkValidTime(img)) || (this.endDateRefresh != null && checkEndDate(img))
475-
|| (this.startDateRefresh != null && checkStartDate(img))
495+
if ((this.timeFilter && checkValidTime(img)) || checkEndDate(img) || checkStartDate(img)
476496
|| (this.imageTypes == ImageTypes.PANORAMIC && !MapillaryImageUtils.IS_PANORAMIC.test(img))
477497
|| (this.imageTypes == ImageTypes.NON_PANORAMIC && MapillaryImageUtils.IS_PANORAMIC.test(img))
478498
|| (this.qualityScore != Float.MIN_VALUE && (MapillaryImageUtils.getQuality(img) < this.qualityScore
@@ -519,6 +539,9 @@ private boolean checkValidTime(INode img) {
519539
* @return {@code true} if the start date is after the image date
520540
*/
521541
private boolean checkStartDate(INode img) {
542+
if (Instant.MIN.equals(startDateRefresh)) {
543+
return false;
544+
}
522545
final Instant start = LocalDateTime.ofInstant(startDateRefresh, ZoneOffset.UTC).toLocalDate()
523546
.atStartOfDay(ZoneOffset.UTC).toInstant();
524547
final Instant imgDate = MapillaryImageUtils.getDate(img);
@@ -530,6 +553,9 @@ private boolean checkStartDate(INode img) {
530553
* @return {@code true} if the end date is before the image date
531554
*/
532555
private boolean checkEndDate(INode img) {
556+
if (Instant.MIN.equals(endDateRefresh)) {
557+
return false;
558+
}
533559
final ZonedDateTime nextDate = LocalDateTime.ofInstant(endDateRefresh, ZoneOffset.UTC).toLocalDate()
534560
.atStartOfDay(ZoneOffset.UTC).plus(1, ChronoUnit.DAYS);
535561
final Instant end = nextDate.toInstant();

src/main/java/org/openstreetmap/josm/plugins/mapillary/gui/dialog/TrafficSignFilter.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,15 @@ public TrafficSignFilter() {
104104
lbox.putClientProperty("layer", layer[0]);
105105
// TODO remove when it listens to layers.
106106
// Maybe get rid of Traffic SIgn/Point object layer filters (no longer needed due to separate layers) OR
107-
// clicking
108-
// on them adds the appropriate layer. Affect hide/show action of layers instead of adding filters?
107+
// clicking on them adds the appropriate layer. Affect hide/show action of layers instead of adding filters?
109108
DeveloperToggleAction.addVisibilitySwitcher(lbox);
110109
}
111110

112-
JCheckBox smartEditMode = new JCheckBox(I18n.tr("Smart Edit Mode"));
113-
smartEditMode.setSelected(Boolean.TRUE.equals(MapillaryProperties.SMART_EDIT.get()));
114-
MapillaryProperties.SMART_EDIT.addListener(l -> updateSmartEdit(l, smartEditMode));
115-
smartEditMode.addItemListener(l -> smartEditMode(l.getStateChange() == ItemEvent.SELECTED));
116-
add(smartEditMode, GBC.eol().anchor(GridBagConstraints.WEST));
111+
JCheckBox smartEditModeBox = new JCheckBox(I18n.tr("Smart Edit Mode"));
112+
smartEditModeBox.setSelected(Boolean.TRUE.equals(MapillaryProperties.SMART_EDIT.get()));
113+
MapillaryProperties.SMART_EDIT.addListener(l -> updateSmartEdit(l, smartEditModeBox));
114+
smartEditModeBox.addItemListener(l -> smartEditMode(l.getStateChange() == ItemEvent.SELECTED));
115+
add(smartEditModeBox, GBC.eol().anchor(GridBagConstraints.WEST));
117116

118117
add(layers, GBC.eol().fill(GridBagConstraints.HORIZONTAL));
119118

@@ -152,7 +151,7 @@ public TrafficSignFilter() {
152151

153152
add(pagination, GBC.eol().anchor(GridBagConstraints.WEST).fill(GridBagConstraints.HORIZONTAL));
154153

155-
this.resetObjects.add(() -> smartEditMode.setSelected(false));
154+
this.resetObjects.add(() -> smartEditModeBox.setSelected(false));
156155
this.resetObjects.add(() -> showRelevantObjs.setSelected(true));
157156
this.resetObjects.add(() -> filterField.setText(""));
158157
this.resetObjects.add(() -> showMaxNumberModel.setValue(100));
@@ -282,7 +281,8 @@ private static void updateDates(String position, IDatePicker<?> modified, IDateP
282281
IDatePicker<?> lastSeen) {
283282
Instant start = firstSeen.getInstant();
284283
Instant end = lastSeen.getInstant();
285-
if (start != null && end != null) {
284+
final boolean knownStartEnd = !Instant.MIN.equals(start) && !Instant.MIN.equals(end);
285+
if (knownStartEnd) {
286286
if (firstSeen.equals(modified) && start.compareTo(end) > 0) {
287287
lastSeen.setInstant(start);
288288
} else if (lastSeen.equals(modified) && start.compareTo(end) > 0) {
@@ -292,13 +292,13 @@ private static void updateDates(String position, IDatePicker<?> modified, IDateP
292292
Filter dateFilter = MapillaryExpertFilterDialog.getInstance().getFilterModel().getFilters().parallelStream()
293293
.filter(p -> p.text.contains(position + "_seen_at")).findFirst().orElseGet(Filter::new);
294294
StringBuilder filterText = new StringBuilder();
295-
if (start != null) {
295+
if (!Instant.MIN.equals(start)) {
296296
filterText.append(position).append("_seen_at > ").append(DateTimeFormatter.ISO_LOCAL_DATE.format(start));
297297
}
298-
if (start != null && end != null) {
298+
if (knownStartEnd) {
299299
filterText.append(" && ");
300300
}
301-
if (end != null) {
301+
if (!Instant.MIN.equals(end)) {
302302
filterText.append(position).append("_seen_at < ").append(DateTimeFormatter.ISO_LOCAL_DATE.format(end));
303303
}
304304
dateFilter.text = filterText.toString();

test/unit/org/openstreetmap/josm/plugins/mapillary/gui/layer/MapillaryLayerTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.openstreetmap.josm.gui.layer.Layer;
3535
import org.openstreetmap.josm.gui.layer.OsmDataLayer;
3636
import org.openstreetmap.josm.gui.layer.imagery.MVTLayer;
37+
import org.openstreetmap.josm.plugins.mapillary.gui.dialog.MapillaryFilterDialog;
3738
import org.openstreetmap.josm.plugins.mapillary.testutils.annotations.MapillaryLayerAnnotation;
3839
import org.openstreetmap.josm.plugins.mapillary.testutils.annotations.MapillaryURLWireMock;
3940
import org.openstreetmap.josm.plugins.mapillary.testutils.annotations.MapillaryURLWireMockErrors;
@@ -60,6 +61,9 @@ void setUp() {
6061
if (MapillaryLayer.hasInstance()) {
6162
try {
6263
MapillaryLayer.getInstance().destroy();
64+
if (MapillaryFilterDialog.hasInstance()) {
65+
MapillaryFilterDialog.getInstance().reset();
66+
}
6367
} catch (IllegalArgumentException illegalArgumentException) {
6468
// Some other test pollutes MapillaryLayer.getInstance, and LayerChangeAdaptor is cleaned up.
6569
// This causes destroy() to fail on the first test.

0 commit comments

Comments
 (0)