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