001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.widgets;
003
004import javax.swing.text.JTextComponent;
005
006import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
007import org.openstreetmap.josm.gui.tagging.ac.AutoCompTextField;
008import org.openstreetmap.josm.tools.Logging;
009import org.openstreetmap.josm.tools.Utils;
010
011/**
012 * An abstract class for ID text fields.
013 *
014 * @param <T> The ID validator class
015 * @since 5765
016 */
017public abstract class AbstractIdTextField<T extends AbstractTextComponentValidator> extends AutoCompTextField<String> {
018
019    protected final transient T validator;
020
021    /**
022     * Constructs a new {@link AbstractIdTextField}
023     * @param klass The validator class
024     */
025    protected AbstractIdTextField(Class<T> klass) {
026        this(klass, 0);
027    }
028
029    /**
030     * Constructs a new {@link AbstractIdTextField}
031     * @param klass The validator class
032     * @param columns The number of columns to use to calculate the preferred width
033     * @see JosmTextField#JosmTextField(int)
034     */
035    protected AbstractIdTextField(Class<T> klass, int columns) {
036        super(columns);
037        T validator = null;
038        try {
039            if (klass != null) {
040                validator = klass.getConstructor(JTextComponent.class).newInstance(this);
041            }
042        } catch (ReflectiveOperationException e) {
043            Logging.error(e);
044        } finally {
045            this.validator = validator;
046        }
047    }
048
049    /**
050     * Performs the field validation
051     */
052    public final void performValidation() {
053        validator.validate();
054    }
055
056    /**
057     * Clears field if content is invalid
058     */
059    public final void clearTextIfInvalid() {
060        if (!validator.isValid())
061            setText("");
062        validator.validate();
063    }
064
065    /**
066     * Reads the id(s).
067     * @return true if at least a valid id has been successfully read, false otherwise
068     */
069    public abstract boolean readIds();
070
071    /**
072     * Tries to set text from clipboard (no effect with invalid or empty clipboard)
073     */
074    public void tryToPasteFromClipboard() {
075        tryToPasteFrom(ClipboardUtils.getClipboardStringContent());
076    }
077
078    /**
079     * Tries to set text from given contents (no effect with invalid or empty contents)
080     * @param contents The text to interpret as ID(s)
081     * @return true if text has been pasted and valid ids have been read
082     */
083    public boolean tryToPasteFrom(String contents) {
084        if (!Utils.isBlank(contents)) {
085            setText(contents.trim());
086            clearTextIfInvalid();
087            return readIds();
088        }
089        return false;
090    }
091}