[11326] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
| 2 | package org.openstreetmap.josm.gui.dialogs.changeset.query;
|
---|
| 3 |
|
---|
| 4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
| 5 |
|
---|
| 6 | import java.time.LocalDate;
|
---|
| 7 | import java.time.ZonedDateTime;
|
---|
| 8 | import java.time.format.DateTimeFormatter;
|
---|
| 9 | import java.time.format.DateTimeParseException;
|
---|
| 10 | import java.time.format.FormatStyle;
|
---|
| 11 |
|
---|
| 12 | import javax.swing.text.JTextComponent;
|
---|
| 13 |
|
---|
| 14 | import org.openstreetmap.josm.gui.widgets.AbstractTextComponentValidator;
|
---|
[12620] | 15 | import org.openstreetmap.josm.tools.Logging;
|
---|
[11326] | 16 |
|
---|
| 17 | /**
|
---|
| 18 | * Validates dates entered as text in a {@link JTextComponent}. Validates the input
|
---|
| 19 | * on the fly and gives feedback about whether the date is valid or not.
|
---|
| 20 | *
|
---|
| 21 | * Dates can be entered in one of four standard formats defined for the current locale.
|
---|
| 22 | * @since 11326 (extracted from AdvancedChangesetQueryPanel)
|
---|
| 23 | */
|
---|
| 24 | public class DateValidator extends AbstractTextComponentValidator {
|
---|
| 25 |
|
---|
| 26 | /**
|
---|
| 27 | * Constructs a new {@code DateValidator} for the given text component.
|
---|
| 28 | * @param tc text component
|
---|
| 29 | */
|
---|
| 30 | public DateValidator(JTextComponent tc) {
|
---|
| 31 | super(tc);
|
---|
| 32 | }
|
---|
| 33 |
|
---|
| 34 | /**
|
---|
| 35 | * Decorates the given text component.
|
---|
| 36 | * @param tc text component to decorate
|
---|
| 37 | * @return new date validator attached to {@code tc}
|
---|
| 38 | */
|
---|
| 39 | public static DateValidator decorate(JTextComponent tc) {
|
---|
| 40 | return new DateValidator(tc);
|
---|
| 41 | }
|
---|
| 42 |
|
---|
| 43 | @Override
|
---|
| 44 | public boolean isValid() {
|
---|
| 45 | return getDate() != null;
|
---|
| 46 | }
|
---|
| 47 |
|
---|
| 48 | /**
|
---|
| 49 | * Returns the standard tooltip text as HTML.
|
---|
| 50 | * @return the standard tooltip text as HTML
|
---|
| 51 | */
|
---|
| 52 | public String getStandardTooltipTextAsHtml() {
|
---|
| 53 | return "<html>" + getStandardTooltipText() + "</html>";
|
---|
| 54 | }
|
---|
| 55 |
|
---|
| 56 | /**
|
---|
| 57 | * Returns the standard tooltip text.
|
---|
| 58 | * @return the standard tooltip text
|
---|
| 59 | */
|
---|
| 60 | public String getStandardTooltipText() {
|
---|
| 61 | final ZonedDateTime now = ZonedDateTime.now();
|
---|
| 62 | return tr(
|
---|
| 63 | "Please enter a date in the usual format for your locale.<br>"
|
---|
| 64 | + "Example: {0}<br>"
|
---|
| 65 | + "Example: {1}<br>"
|
---|
| 66 | + "Example: {2}<br>"
|
---|
| 67 | + "Example: {3}<br>",
|
---|
| 68 | DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).format(now),
|
---|
| 69 | DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).format(now),
|
---|
| 70 | DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).format(now),
|
---|
| 71 | DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).format(now)
|
---|
| 72 | );
|
---|
| 73 | }
|
---|
| 74 |
|
---|
| 75 | @Override
|
---|
| 76 | public void validate() {
|
---|
| 77 | if (!isValid()) {
|
---|
| 78 | String msg = "<html>The current value isn't a valid date.<br>" + getStandardTooltipText()+ "</html>";
|
---|
| 79 | feedbackInvalid(msg);
|
---|
| 80 | } else {
|
---|
| 81 | String msg = "<html>" + getStandardTooltipText() + "</html>";
|
---|
| 82 | feedbackValid(msg);
|
---|
| 83 | }
|
---|
| 84 | }
|
---|
| 85 |
|
---|
| 86 | /**
|
---|
| 87 | * Returns the date.
|
---|
| 88 | * @return the date
|
---|
| 89 | */
|
---|
| 90 | public LocalDate getDate() {
|
---|
| 91 | for (final FormatStyle format: FormatStyle.values()) {
|
---|
| 92 | DateTimeFormatter df = DateTimeFormatter.ofLocalizedDate(format);
|
---|
| 93 | try {
|
---|
| 94 | return LocalDate.parse(getComponent().getText(), df);
|
---|
| 95 | } catch (DateTimeParseException e) {
|
---|
| 96 | // Try next format
|
---|
[12620] | 97 | Logging.trace(e);
|
---|
[11326] | 98 | }
|
---|
| 99 | }
|
---|
| 100 | return null;
|
---|
| 101 | }
|
---|
| 102 | }
|
---|