source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationDialogManager.java@ 9246

Last change on this file since 9246 was 9246, checked in by Don-vip, 8 years ago

javadoc update

  • Property svn:eol-style set to native
File size: 9.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs.relation;
3
4import java.awt.Point;
5import java.awt.event.WindowAdapter;
6import java.awt.event.WindowEvent;
7import java.util.HashMap;
8import java.util.Iterator;
9import java.util.Map;
10import java.util.Map.Entry;
11import java.util.Objects;
12
13import org.openstreetmap.josm.data.osm.Relation;
14import org.openstreetmap.josm.gui.MapView;
15import org.openstreetmap.josm.gui.layer.Layer;
16import org.openstreetmap.josm.gui.layer.OsmDataLayer;
17
18/**
19 * RelationDialogManager keeps track of the open relation editors.
20 *
21 */
22public class RelationDialogManager extends WindowAdapter implements MapView.LayerChangeListener {
23
24 /** keeps track of open relation editors */
25 private static RelationDialogManager relationDialogManager;
26
27 /**
28 * Replies the singleton {@link RelationDialogManager}
29 *
30 * @return the singleton {@link RelationDialogManager}
31 */
32 public static RelationDialogManager getRelationDialogManager() {
33 if (RelationDialogManager.relationDialogManager == null) {
34 RelationDialogManager.relationDialogManager = new RelationDialogManager();
35 MapView.addLayerChangeListener(RelationDialogManager.relationDialogManager);
36 }
37 return RelationDialogManager.relationDialogManager;
38 }
39
40 /**
41 * Helper class for keeping the context of a relation editor. A relation editor
42 * is open for a specific relation managed by a specific {@link OsmDataLayer}
43 *
44 */
45 private static class DialogContext {
46 public final Relation relation;
47 public final OsmDataLayer layer;
48
49 DialogContext(OsmDataLayer layer, Relation relation) {
50 this.layer = layer;
51 this.relation = relation;
52 }
53
54 @Override
55 public int hashCode() {
56 final int prime = 31;
57 int result = 1;
58 result = prime * result + ((layer == null) ? 0 : layer.hashCode());
59 result = prime * result + ((relation == null) ? 0 : relation.hashCode());
60 return result;
61 }
62
63 @Override
64 public boolean equals(Object obj) {
65 if (this == obj)
66 return true;
67 if (obj == null)
68 return false;
69 if (getClass() != obj.getClass())
70 return false;
71 DialogContext other = (DialogContext) obj;
72 if (layer == null) {
73 if (other.layer != null)
74 return false;
75 } else if (!layer.equals(other.layer))
76 return false;
77 if (relation == null) {
78 if (other.relation != null)
79 return false;
80 } else if (!relation.equals(other.relation))
81 return false;
82 return true;
83 }
84
85 public boolean matchesLayer(OsmDataLayer layer) {
86 if (layer == null) return false;
87 return this.layer.equals(layer);
88 }
89
90 @Override
91 public String toString() {
92 return "[Context: layer=" + layer.getName() + ",relation=" + relation.getId() + ']';
93 }
94 }
95
96 /** the map of open dialogs */
97 private final Map<DialogContext, RelationEditor> openDialogs;
98
99 /**
100 * constructor
101 */
102 public RelationDialogManager() {
103 openDialogs = new HashMap<>();
104 }
105
106 /**
107 * Register the relation editor for a relation managed by a
108 * {@link OsmDataLayer}.
109 *
110 * @param layer the layer
111 * @param relation the relation
112 * @param editor the editor
113 */
114 public void register(OsmDataLayer layer, Relation relation, RelationEditor editor) {
115 if (relation == null) {
116 relation = new Relation();
117 }
118 DialogContext context = new DialogContext(layer, relation);
119 openDialogs.put(context, editor);
120 editor.addWindowListener(this);
121 }
122
123 public void updateContext(OsmDataLayer layer, Relation relation, RelationEditor editor) {
124 // lookup the entry for editor and remove it
125 //
126 for (Iterator<Entry<DialogContext, RelationEditor>> it = openDialogs.entrySet().iterator(); it.hasNext();) {
127 Entry<DialogContext, RelationEditor> entry = it.next();
128 if (Objects.equals(entry.getValue(), editor)) {
129 it.remove();
130 break;
131 }
132 }
133 // don't add a window listener. Editor is already known to the relation dialog manager
134 //
135 DialogContext context = new DialogContext(layer, relation);
136 openDialogs.put(context, editor);
137 }
138
139 /**
140 * Closes the editor open for a specific layer and a specific relation.
141 *
142 * @param layer the layer
143 * @param relation the relation
144 */
145 public void close(OsmDataLayer layer, Relation relation) {
146 DialogContext context = new DialogContext(layer, relation);
147 RelationEditor editor = openDialogs.get(context);
148 if (editor != null) {
149 editor.setVisible(false);
150 }
151 }
152
153 /**
154 * Replies true if there is an open relation editor for the relation managed
155 * by the given layer. Replies false if relation is null.
156 *
157 * @param layer the layer
158 * @param relation the relation. May be null.
159 * @return true if there is an open relation editor for the relation managed
160 * by the given layer; false otherwise
161 */
162 public boolean isOpenInEditor(OsmDataLayer layer, Relation relation) {
163 if (relation == null) return false;
164 DialogContext context = new DialogContext(layer, relation);
165 return openDialogs.keySet().contains(context);
166
167 }
168
169 /**
170 * Replies the editor for the relation managed by layer. Null, if no such editor
171 * is currently open. Returns null, if relation is null.
172 *
173 * @param layer the layer
174 * @param relation the relation
175 * @return the editor for the relation managed by layer. Null, if no such editor
176 * is currently open.
177 *
178 * @see #isOpenInEditor(OsmDataLayer, Relation)
179 */
180 public RelationEditor getEditorForRelation(OsmDataLayer layer, Relation relation) {
181 if (relation == null) return null;
182 DialogContext context = new DialogContext(layer, relation);
183 return openDialogs.get(context);
184 }
185
186 /**
187 * called when a layer is removed
188 *
189 */
190 @Override
191 public void layerRemoved(Layer oldLayer) {
192 if (!(oldLayer instanceof OsmDataLayer))
193 return;
194 OsmDataLayer dataLayer = (OsmDataLayer) oldLayer;
195
196 Iterator<Entry<DialogContext, RelationEditor>> it = openDialogs.entrySet().iterator();
197 while (it.hasNext()) {
198 Entry<DialogContext, RelationEditor> entry = it.next();
199 if (entry.getKey().matchesLayer(dataLayer)) {
200 RelationEditor editor = entry.getValue();
201 it.remove();
202 editor.setVisible(false);
203 editor.dispose();
204 }
205 }
206 }
207
208 @Override
209 public void activeLayerChange(Layer oldLayer, Layer newLayer) {
210 // do nothing
211 }
212
213 @Override
214 public void layerAdded(Layer newLayer) {
215 // do nothing
216 }
217
218 @Override
219 public void windowClosed(WindowEvent e) {
220 RelationEditor editor = (RelationEditor) e.getWindow();
221 for (Iterator<Entry<DialogContext, RelationEditor>> it = openDialogs.entrySet().iterator(); it.hasNext();) {
222 if (editor.equals(it.next().getValue())) {
223 it.remove();
224 break;
225 }
226 }
227 }
228
229 /**
230 * Replies true, if there is another open {@link RelationEditor} whose
231 * upper left corner is close to <code>p</code>.
232 *
233 * @param p the reference point to check
234 * @param thisEditor the current editor
235 * @return true, if there is another open {@link RelationEditor} whose
236 * upper left corner is close to <code>p</code>.
237 */
238 protected boolean hasEditorWithCloseUpperLeftCorner(Point p, RelationEditor thisEditor) {
239 for (RelationEditor editor: openDialogs.values()) {
240 if (editor == thisEditor) {
241 continue;
242 }
243 Point corner = editor.getLocation();
244 if (p.x >= corner.x -5 && corner.x + 5 >= p.x
245 && p.y >= corner.y -5 && corner.y + 5 >= p.y)
246 return true;
247 }
248 return false;
249 }
250
251 /**
252 * Positions a {@link RelationEditor} on the screen. Tries to center it on the
253 * screen. If it hide another instance of an editor at the same position this
254 * method tries to reposition <code>editor</code> by moving it slightly down and
255 * slightly to the right.
256 *
257 * @param editor the editor
258 */
259 public void positionOnScreen(RelationEditor editor) {
260 if (editor == null) return;
261 if (!openDialogs.isEmpty()) {
262 Point corner = editor.getLocation();
263 while (hasEditorWithCloseUpperLeftCorner(corner, editor)) {
264 // shift a little, so that the dialogs are not exactly on top of each other
265 corner.x += 20;
266 corner.y += 20;
267 }
268 editor.setLocation(corner);
269 }
270 }
271
272}
Note: See TracBrowser for help on using the repository browser.