Ignore:
Timestamp:
2017-05-10T23:00:16+02:00 (7 years ago)
Author:
michael2402
Message:

Allow to globally add the new selection listeners that get detailed events.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/event/SelectionEventManager.java

    r12096 r12098  
    22package org.openstreetmap.josm.data.osm.event;
    33
    4 import java.util.Collection;
    54import java.util.Collections;
    65import java.util.HashSet;
    76import java.util.List;
    87import java.util.Objects;
    9 import java.util.Set;
    108import java.util.concurrent.CopyOnWriteArrayList;
    119import java.util.stream.Stream;
     
    1715import org.openstreetmap.josm.data.osm.DataSelectionListener;
    1816import org.openstreetmap.josm.data.osm.DataSet;
    19 import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2017import org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode;
    2118import org.openstreetmap.josm.gui.layer.MainLayerManager;
     
    4542    }
    4643
    47     private static class ListenerInfo {
     44    private abstract static class AbstractListenerInfo {
     45        abstract void fire(SelectionChangeEvent event);
     46    }
     47
     48    private static class ListenerInfo extends AbstractListenerInfo {
    4849        private final SelectionChangedListener listener;
    4950
    5051        ListenerInfo(SelectionChangedListener listener) {
    5152            this.listener = listener;
     53        }
     54
     55        @Override
     56        void fire(SelectionChangeEvent event) {
     57            listener.selectionChanged(event.getSelection());
    5258        }
    5359
     
    6672    }
    6773
    68     private Collection<? extends OsmPrimitive> selection;
    69     private final CopyOnWriteArrayList<ListenerInfo> inEDTListeners = new CopyOnWriteArrayList<>();
    70     private final CopyOnWriteArrayList<ListenerInfo> normalListeners = new CopyOnWriteArrayList<>();
     74    private static class DataListenerInfo extends AbstractListenerInfo {
     75        private final DataSelectionListener listener;
     76
     77        DataListenerInfo(DataSelectionListener listener) {
     78            this.listener = listener;
     79        }
     80
     81        @Override
     82        void fire(SelectionChangeEvent event) {
     83            listener.selectionChanged(event);
     84        }
     85
     86        @Override
     87        public int hashCode() {
     88            return Objects.hash(listener);
     89        }
     90
     91        @Override
     92        public boolean equals(Object o) {
     93            if (this == o) return true;
     94            if (o == null || getClass() != o.getClass()) return false;
     95            DataListenerInfo that = (DataListenerInfo) o;
     96            return Objects.equals(listener, that.listener);
     97        }
     98    }
     99
     100    private final CopyOnWriteArrayList<AbstractListenerInfo> inEDTListeners = new CopyOnWriteArrayList<>();
     101    private final CopyOnWriteArrayList<AbstractListenerInfo> immedatelyListeners = new CopyOnWriteArrayList<>();
    71102
    72103    /**
     
    82113    /**
    83114     * Registers a new {@code SelectionChangedListener}.
     115     *
     116     * It is preferred to add a DataSelectionListener - that listener will receive more information about the event.
    84117     * @param listener listener to add
    85118     * @param fireMode Set this to IN_EDT_CONSOLIDATED if you want the event to be fired in the EDT thread.
     
    92125            inEDTListeners.addIfAbsent(new ListenerInfo(listener));
    93126        } else {
    94             normalListeners.addIfAbsent(new ListenerInfo(listener));
    95         }
     127            immedatelyListeners.addIfAbsent(new ListenerInfo(listener));
     128        }
     129    }
     130
     131    /**
     132     * Adds a selection listener that gets notified for selections immediately.
     133     * @param listener The listener to add.
     134     * @since 12098
     135     */
     136    public void addSelectionListener(DataSelectionListener listener) {
     137        immedatelyListeners.addIfAbsent(new DataListenerInfo(listener));
     138    }
     139
     140    /**
     141     * Adds a selection listener that gets notified for selections later in the EDT thread.
     142     * Events are sent in the right order but may be delayed.
     143     * @param listener The listener to add.
     144     * @since 12098
     145     */
     146    public void addSelectionListenerForEdt(DataSelectionListener listener) {
     147        inEDTListeners.addIfAbsent(new DataListenerInfo(listener));
    96148    }
    97149
     
    101153     */
    102154    public void removeSelectionListener(SelectionChangedListener listener) {
    103         ListenerInfo searchListener = new ListenerInfo(listener);
     155        remove(new ListenerInfo(listener));
     156    }
     157
     158    /**
     159     * Unregisters a {@code DataSelectionListener}.
     160     * @param listener listener to remove
     161     * @since 12098
     162     */
     163    public void removeSelectionListener(DataSelectionListener listener) {
     164        remove(new DataListenerInfo(listener));
     165    }
     166
     167    private void remove(AbstractListenerInfo searchListener) {
    104168        inEDTListeners.remove(searchListener);
    105         normalListeners.remove(searchListener);
     169        immedatelyListeners.remove(searchListener);
    106170    }
    107171
     
    130194
    131195    @Override
    132     public void selectionChanged(SelectionChangeEvent e) {
    133         Set<OsmPrimitive> newSelection = e.getSelection();
    134         fireEvents(normalListeners, newSelection);
    135         selection = newSelection;
    136         SwingUtilities.invokeLater(edtRunnable);
    137     }
    138 
    139     private static void fireEvents(List<ListenerInfo> listeners, Collection<? extends OsmPrimitive> newSelection) {
    140         for (ListenerInfo listener: listeners) {
    141             listener.listener.selectionChanged(newSelection);
    142         }
    143     }
    144 
    145     private final Runnable edtRunnable = () -> {
    146         if (selection != null) {
    147             fireEvents(inEDTListeners, selection);
    148         }
    149     };
     196    public void selectionChanged(SelectionChangeEvent event) {
     197        fireEvent(immedatelyListeners, event);
     198        SwingUtilities.invokeLater(() -> fireEvent(inEDTListeners, event));
     199    }
     200
     201    private static void fireEvent(List<AbstractListenerInfo> listeners, SelectionChangeEvent event) {
     202        for (AbstractListenerInfo listener: listeners) {
     203            listener.fire(event);
     204        }
     205    }
    150206
    151207    /**
     
    155211    public void resetState() {
    156212        inEDTListeners.clear();
    157         normalListeners.clear();
     213        immedatelyListeners.clear();
    158214        Main.getLayerManager().addAndFireActiveLayerChangeListener(this);
    159215    }
Note: See TracChangeset for help on using the changeset viewer.