Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ dependencies {
testImplementation("org.awaitility:awaitility:4.0.3")
testImplementation("org.jmockit:jmockit:1.46") { because("versions >= 1.47 are incompatible with JOSM, see https://josm.openstreetmap.de/ticket/18200") }
testImplementation("com.github.spotbugs:spotbugs-annotations:4.0.6")
packIntoJar("org.jdatepicker:jdatepicker:1.3.4")
}

sourceSets {
Expand Down
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ plugin.main.version=16402
# Please check, if the specified version is available for download from https://josm.openstreetmap.de/download/ .
# If not, choose the next higher number that is available, or the gradle build will break.
plugin.compile.version=16402
plugin.requires=apache-commons;apache-http;javafx
# The datepicker plugin is currently in the source tree. TODO fix
plugin.requires=apache-commons;apache-http

# Character encoding of Gradle files
systemProp.file.encoding=utf-8
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.datepicker;

import org.openstreetmap.josm.plugins.Plugin;
import org.openstreetmap.josm.plugins.PluginInformation;

/**
* The plugin initializer for the DatePicker plugin
*
* @author Taylor Smock
*/
public final class DatePicker extends Plugin {
public DatePicker(PluginInformation info) {
super(info);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.datepicker;

import java.lang.reflect.InvocationTargetException;
import java.time.LocalDate;
import java.util.function.Consumer;

import javax.swing.JComponent;

import org.openstreetmap.josm.plugins.datepicker.impl.DatePickerSwing;
import org.openstreetmap.josm.spi.preferences.Config;
import org.openstreetmap.josm.tools.Logging;

/**
* This is a generic interface for date pickers. Use
* {@link IDatePicker#getNewDatePicker} to get a new date picker. It uses the
* {@code "datepicker.classname"} setting to determine the appropriate class.
*
* @author Taylor Smock
*/
public interface IDatePicker<T extends JComponent> {
/**
* Set the date
*
* @param date The date to set
*/
void setDate(LocalDate date);

/**
* Get the date
*
* @return The date
*/
LocalDate getDate();

/**
* Get the component
*
* @return The component to be added to a UI
*/
T getComponent();

/**
* Reset the component
*/
void reset();

/**
* Add an event handler for when the date changes
*
* @param function The function to call when the date changes
*/
void addEventHandler(Consumer<IDatePicker<?>> function);

/**
* Get a new date picker. The implementation may change. Only rely on this
* interface.
*
* @return A new date picker
*/
@SuppressWarnings("unchecked")
static IDatePicker<? extends JComponent> getNewDatePicker() {
String datePicker = Config.getPref().get("datepicker.classname",
"org.openstreetmap.josm.plugins.datepicker.impl.DatePickerJDatePicker");
try {
Class<?> cls = Class.forName(datePicker);
Object instance = cls.getConstructor().newInstance();
if (instance instanceof IDatePicker) {
return (IDatePicker<? extends JComponent>) instance;
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
Logging.error(e);
}
// Fall back to basic text entry
return new DatePickerSwing();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.datepicker.impl;

import java.time.LocalDate;
import java.time.temporal.ChronoField;
import java.util.Properties;
import java.util.function.Consumer;

import org.jdatepicker.impl.DateComponentFormatter;
import org.jdatepicker.impl.JDatePanelImpl;
import org.jdatepicker.impl.JDatePickerImpl;
import org.jdatepicker.impl.UtilDateModel;
import org.openstreetmap.josm.plugins.datepicker.IDatePicker;

import static org.openstreetmap.josm.tools.I18n.tr;

/**
* An implementation of the IDatePicker interface. Do NOT directly use. This may
* be removed at any time.
*
* @author Taylor Smock
*
*/
public class DatePickerJDatePicker implements IDatePicker<JDatePickerImpl> {
final static Properties PROPERTIES = new Properties();
private boolean reset = true;
static {
PROPERTIES.put("text.today", tr("Today"));
PROPERTIES.put("text.month", tr("Month"));
PROPERTIES.put("text.year", tr("Year"));
PROPERTIES.put("text.clear", tr("Clear"));
}

private JDatePickerImpl datePicker;

public DatePickerJDatePicker() {
UtilDateModel model = new UtilDateModel();
JDatePanelImpl datePanel = new JDatePanelImpl(model, PROPERTIES);
this.datePicker = new JDatePickerImpl(datePanel, new DateComponentFormatter());
this.datePicker.setTextEditable(true);
this.datePicker.setShowYearButtons(true);
}

@Override
public void setDate(LocalDate date) {
if (date != null) {
this.datePicker.getModel().setDate(date.get(ChronoField.YEAR_OF_ERA), date.getMonthValue(),
date.getDayOfMonth());
} else
reset();
}

@Override
public LocalDate getDate() {
return this.datePicker.getJFormattedTextField().getText().trim().isEmpty() ? null
: LocalDate.of(this.datePicker.getModel().getYear(), this.datePicker.getModel().getMonth(),
this.datePicker.getModel().getDay());
}

@Override
public JDatePickerImpl getComponent() {
return this.datePicker;
}

@Override
public void reset() {
this.datePicker.getJFormattedTextField().setText("");
}

@Override
public void addEventHandler(Consumer<IDatePicker<?>> function) {
this.datePicker.addActionListener(action -> function.accept(this));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.datepicker.impl;

import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAccessor;
import java.util.function.Consumer;

import org.openstreetmap.josm.gui.widgets.JosmTextField;
import org.openstreetmap.josm.plugins.datepicker.IDatePicker;
import org.openstreetmap.josm.tools.Logging;
import org.openstreetmap.josm.tools.Utils;

/**
* This is a fall back date picker. It is used when the set date picker fails to
* load, for what ever reason. Do not directly use this implementation.
*
* @author Taylor Smock
*/
public class DatePickerSwing implements IDatePicker<JosmTextField> {
private LocalDate date;
private final JosmTextField component = new JosmTextField("", 12);

public DatePickerSwing() {
super();
component.setToolTipText("YYYY-MM-DD");
}

@Override
public void setDate(LocalDate date) {
if (date == null) {
try {
TemporalAccessor temporal = DateTimeFormatter.ISO_DATE.parse(component.getText());
this.date = LocalDate.from(temporal);
} catch (DateTimeParseException e) {
if (!Utils.removeWhiteSpaces(component.getText()).isEmpty()) {
Logging.trace(e);
component.setText("");
}
}
} else {
this.date = date;
component.setText(date.format(DateTimeFormatter.ISO_DATE));
}
}

@Override
public LocalDate getDate() {
return date;
}

@Override
public JosmTextField getComponent() {
return component;
}

@Override
public void reset() {
component.setText("");
}

@Override
public void addEventHandler(Consumer<IDatePicker<?>> function) {
component.addFocusListener(new FocusListener() {

@Override
public void focusGained(FocusEvent e) {
// Do nothing
}

@Override
public void focusLost(FocusEvent e) {
setDate(null);
function.accept(DatePickerSwing.this);
}
});
}

}

This file was deleted.

Loading