source: josm/trunk/src/org/openstreetmap/josm/data/osm/event/SelectionEventManager.java@ 2912

Last change on this file since 2912 was 2912, checked in by jttt, 14 years ago

Fixed #4330 java.lang.ArrayIndexOutOfBoundsException: 6 >= 6, added SelectionEventManager (similar to DatasetEventManager)

  • Property svn:mime-type set to text/plain
File size: 3.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm.event;
3
4import java.util.Collection;
5import java.util.List;
6import java.util.concurrent.CopyOnWriteArrayList;
7
8import javax.swing.SwingUtilities;
9
10import org.openstreetmap.josm.data.SelectionChangedListener;
11import org.openstreetmap.josm.data.osm.DataSet;
12import org.openstreetmap.josm.data.osm.OsmPrimitive;
13import org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode;
14
15/**
16 * Similar like {@link DatasetEventManager}, just for selection events. Because currently selection changed
17 * event are global, only FIRE_IN_EDT and FIRE_EDT_CONSOLIDATED modes are really useful
18 *
19 */
20public class SelectionEventManager implements SelectionChangedListener {
21
22 private static final SelectionEventManager instance = new SelectionEventManager();
23
24 public static SelectionEventManager getInstance() {
25 return instance;
26 }
27
28 private static class ListenerInfo {
29 final SelectionChangedListener listener;
30
31 public ListenerInfo(SelectionChangedListener listener, boolean consolidate) {
32 this.listener = listener;
33 }
34
35 @Override
36 public int hashCode() {
37 return listener.hashCode();
38 }
39
40 @Override
41 public boolean equals(Object o) {
42 return o instanceof ListenerInfo && ((ListenerInfo)o).listener == listener;
43 }
44 }
45
46 private Collection<? extends OsmPrimitive> selection;
47 private final CopyOnWriteArrayList<ListenerInfo> inEDTListeners = new CopyOnWriteArrayList<ListenerInfo>();
48 private final CopyOnWriteArrayList<ListenerInfo> normalListeners = new CopyOnWriteArrayList<ListenerInfo>();
49
50 public SelectionEventManager() {
51 DataSet.selListeners.add(this);
52 }
53
54 public void addSelectionListener(SelectionChangedListener listener, FireMode fireMode) {
55 if (fireMode == FireMode.IN_EDT)
56 throw new UnsupportedOperationException("IN_EDT mode not supported, you probably want to use IN_EDT_CONSOLIDATED.");
57 if (fireMode == FireMode.IN_EDT || fireMode == FireMode.IN_EDT_CONSOLIDATED) {
58 inEDTListeners.addIfAbsent(new ListenerInfo(listener, fireMode == FireMode.IN_EDT_CONSOLIDATED));
59 } else {
60 normalListeners.addIfAbsent(new ListenerInfo(listener, false));
61 }
62 }
63
64 public void removeSelectionListener(SelectionChangedListener listener) {
65 ListenerInfo searchListener = new ListenerInfo(listener, false);
66 inEDTListeners.remove(searchListener);
67 normalListeners.remove(searchListener);
68 }
69
70 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
71 fireEvents(normalListeners, newSelection);
72 selection = newSelection;
73 SwingUtilities.invokeLater(edtRunnable);
74 }
75
76 private void fireEvents(List<ListenerInfo> listeners, Collection<? extends OsmPrimitive> newSelection) {
77 for (ListenerInfo listener: listeners) {
78 listener.listener.selectionChanged(newSelection);
79 }
80 }
81
82 private final Runnable edtRunnable = new Runnable() {
83 public void run() {
84 if (selection != null) {
85 fireEvents(inEDTListeners, selection);
86 }
87 }
88 };
89
90}
Note: See TracBrowser for help on using the repository browser.