001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.util;
003
004import java.util.ArrayList;
005import java.util.LinkedHashSet;
006import java.util.List;
007import java.util.Set;
008
009import javax.swing.CellEditor;
010import javax.swing.event.CellEditorListener;
011import javax.swing.event.ChangeEvent;
012
013/**
014 * Utility class used to ease implementation of {@link CellEditor} interface,
015 * or one of its sub-interfaces, for classes that cannot extend {@link javax.swing.AbstractCellEditor}.
016 * @since 6912
017 */
018public class CellEditorSupport {
019    private final CellEditor editor;
020    private final Set<CellEditorListener> listeners;
021
022    /**
023     * Constructs a new {@code CellEditorSupport}.
024     * @param editor The cell editor backed by this
025     */
026    public CellEditorSupport(CellEditor editor) {
027        this.editor = editor;
028        this.listeners = new LinkedHashSet<>();
029    }
030
031    protected List<CellEditorListener> getListeners() {
032        synchronized (this) {
033            return new ArrayList<>(listeners);
034        }
035    }
036
037    /**
038     * Worker for {@link CellEditor#addCellEditorListener(CellEditorListener)} method.
039     * @param l the CellEditorListener
040     */
041    public final void addCellEditorListener(CellEditorListener l) {
042        synchronized (this) {
043            if (l != null && !listeners.contains(l)) {
044                listeners.add(l);
045            }
046        }
047    }
048
049    /**
050     * Worker for {@link CellEditor#removeCellEditorListener(CellEditorListener)} method.
051     * @param l the CellEditorListener
052     */
053    public final void removeCellEditorListener(CellEditorListener l) {
054        synchronized (this) {
055            if (l != null && listeners.contains(l)) {
056                listeners.remove(l);
057            }
058        }
059    }
060
061    /**
062     * Fires "editing canceled" event to listeners.
063     */
064    public final void fireEditingCanceled() {
065        for (CellEditorListener listener: getListeners()) {
066            listener.editingCanceled(new ChangeEvent(editor));
067        }
068    }
069
070    /**
071     * Fires "editing stopped" event to listeners.
072     */
073    public final void fireEditingStopped() {
074        for (CellEditorListener listener: getListeners()) {
075            listener.editingStopped(new ChangeEvent(editor));
076        }
077    }
078}