source: josm/trunk/src/org/openstreetmap/josm/gui/layer/Layer.java@ 2619

Last change on this file since 2619 was 2619, checked in by Gubaer, 14 years ago

Global public list of layer change listeners is @deprecated

  • Property svn:eol-style set to native
File size: 9.8 KB
Line 
1// License: GPL. See LICENSE file for details.
2
3package org.openstreetmap.josm.gui.layer;
4
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.Component;
8import java.awt.Graphics2D;
9import java.awt.event.ActionEvent;
10import java.beans.PropertyChangeListener;
11import java.beans.PropertyChangeSupport;
12import java.io.File;
13import java.util.Collection;
14import java.util.concurrent.CopyOnWriteArrayList;
15
16import javax.swing.AbstractAction;
17import javax.swing.Icon;
18
19import org.openstreetmap.josm.actions.GpxExportAction;
20import org.openstreetmap.josm.actions.SaveAction;
21import org.openstreetmap.josm.actions.SaveAsAction;
22import org.openstreetmap.josm.data.Bounds;
23import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
24import org.openstreetmap.josm.gui.MapView;
25import org.openstreetmap.josm.tools.Destroyable;
26import org.openstreetmap.josm.tools.ImageProvider;
27
28/**
29 * A layer encapsulates the gui component of one dataset and its representation.
30 *
31 * Some layers may display data directly imported from OSM server. Other only
32 * display background images. Some can be edited, some not. Some are static and
33 * other changes dynamically (auto-updated).
34 *
35 * Layers can be visible or not. Most actions the user can do applies only on
36 * selected layers. The available actions depend on the selected layers too.
37 *
38 * All layers are managed by the MapView. They are displayed in a list to the
39 * right of the screen.
40 *
41 * @author imi
42 */
43abstract public class Layer implements Destroyable, MapViewPaintable {
44 static public final String VISIBLE_PROP = Layer.class.getName() + ".visible";
45 static public final String NAME_PROP = Layer.class.getName() + ".name";
46
47 /** keeps track of property change listeners */
48 protected PropertyChangeSupport propertyChangeSupport;
49
50 /**
51 * Interface to notify listeners of the change of the active layer.
52 * @author imi
53 */
54 public interface LayerChangeListener {
55 void activeLayerChange(Layer oldLayer, Layer newLayer);
56 void layerAdded(Layer newLayer);
57 void layerRemoved(Layer oldLayer);
58 }
59
60 /**
61 * The listener of the active layer changes. You may register/deregister yourself
62 * while an LayerChangeListener - action is executed.
63 *
64 * @deprecated use {@see #addLayerChangeListener(LayerChangeListener)}
65 * and {@see #removeLayerChangeListener(LayerChangeListener)}
66 */
67 @Deprecated
68 public static final Collection<LayerChangeListener> listeners = new CopyOnWriteArrayList<LayerChangeListener>();
69
70 /**
71 * Adds a layer change listener
72 *
73 * @param listener the listener. Ignored if null or already registered.
74 */
75 public static void addLayerChangeListener(LayerChangeListener listener) {
76 if (listener != null && ! listeners.contains(listener)) {
77 listeners.add(listener);
78 }
79 }
80
81 /**
82 * Removes a layer change listener
83 *
84 * @param listener the listener. Ignored if null or already registered.
85 */
86 public static void removeLayerChangeListener(LayerChangeListener listener) {
87 if (listener != null && listeners.contains(listener)) {
88 listeners.remove(listener);
89 }
90 }
91
92 /**
93 * The visibility state of the layer.
94 *
95 */
96 private boolean visible = true;
97
98 /**
99 * The layer should be handled as a background layer in automatic handling
100 *
101 */
102 private boolean background = false;
103
104 /**
105 * The name of this layer.
106 *
107 */
108 private String name;
109
110 /**
111 * If a file is associated with this layer, this variable should be set to it.
112 */
113 private File associatedFile;
114
115 /**
116 * Create the layer and fill in the necessary components.
117 */
118 public Layer(String name) {
119 this.propertyChangeSupport = new PropertyChangeSupport(this);
120 setName(name);
121 }
122
123 /**
124 * Paint the dataset using the engine set.
125 * @param mv The object that can translate GeoPoints to screen coordinates.
126 */
127 abstract public void paint(Graphics2D g, MapView mv, Bounds box);
128 /**
129 * Return a representative small image for this layer. The image must not
130 * be larger than 64 pixel in any dimension.
131 */
132 abstract public Icon getIcon();
133
134 /**
135 * @return A small tooltip hint about some statistics for this layer.
136 */
137 abstract public String getToolTipText();
138
139 /**
140 * Merges the given layer into this layer. Throws if the layer types are
141 * incompatible.
142 * @param from The layer that get merged into this one. After the merge,
143 * the other layer is not usable anymore and passing to one others
144 * mergeFrom should be one of the last things to do with a layer.
145 */
146 abstract public void mergeFrom(Layer from);
147
148 /**
149 * @param other The other layer that is tested to be mergable with this.
150 * @return Whether the other layer can be merged into this layer.
151 */
152 abstract public boolean isMergable(Layer other);
153
154 abstract public void visitBoundingBox(BoundingXYVisitor v);
155
156 abstract public Object getInfoComponent();
157
158 abstract public Component[] getMenuEntries();
159
160 /**
161 * Called, when the layer is removed from the mapview and is going to be
162 * destroyed.
163 *
164 * This is because the Layer constructor can not add itself safely as listener
165 * to the layerlist dialog, because there may be no such dialog yet (loaded
166 * via command line parameter).
167 */
168 public void destroy() {}
169
170 public File getAssociatedFile() { return associatedFile; }
171 public void setAssociatedFile(File file) { associatedFile = file; }
172
173 /**
174 * Replies the name of the layer
175 *
176 * @return the name of the layer
177 */
178 public String getName() {
179 return name;
180 }
181
182 /**
183 * Sets the name of the layer
184 *
185 *@param name the name. If null, the name is set to the empty string.
186 *
187 */
188 public void setName(String name) {
189 if (name == null) {
190 name = "";
191 }
192 String oldValue = this.name;
193 this.name = name;
194 if (!this.name.equals(oldValue)) {
195 propertyChangeSupport.firePropertyChange(NAME_PROP, oldValue, this.name);
196 }
197 }
198
199 /**
200 * Replies true if this layer is a background layer
201 *
202 * @return true if this layer is a background layer
203 */
204 public boolean isBackgroundLayer() {
205 return background;
206 }
207
208 /**
209 * Sets whether this layer is a background layer
210 *
211 * @param background true, if this layer is a background layer
212 */
213 public void setBackgroundLayer(boolean background) {
214 this.background = background;
215 }
216
217 /**
218 * Sets the visibility of this layer. Emits property change event for
219 * property {@see #VISIBLE_PROP}.
220 *
221 * @param visible true, if the layer is visible; false, otherwise.
222 */
223 public void setVisible(boolean visible) {
224 boolean oldValue = this.visible;
225 this.visible = visible;
226 if (oldValue != this.visible) {
227 fireVisibleChanged(oldValue, this.visible);
228 }
229 }
230
231 /**
232 * Replies true if this layer is visible. False, otherwise.
233 * @return true if this layer is visible. False, otherwise.
234 */
235 public boolean isVisible() {
236 return visible;
237 }
238
239 /**
240 * Toggles the visibility state of this layer.
241 */
242 public void toggleVisible() {
243 setVisible(!isVisible());
244 }
245
246 /**
247 * Adds a {@see PropertyChangeListener}
248 *
249 * @param listener the listener
250 */
251 public void addPropertyChangeListener(PropertyChangeListener listener) {
252 propertyChangeSupport.addPropertyChangeListener(listener);
253 }
254
255 /**
256 * Removes a {@see PropertyChangeListener}
257 *
258 * @param listener the listener
259 */
260 public void removePropertyChangeListener(PropertyChangeListener listener) {
261 propertyChangeSupport.removePropertyChangeListener(listener);
262 }
263
264 /**
265 * fires a property change for the property {@see #VISIBLE_PROP}
266 *
267 * @param oldValue the old value
268 * @param newValue the new value
269 */
270 protected void fireVisibleChanged(boolean oldValue, boolean newValue) {
271 propertyChangeSupport.firePropertyChange(VISIBLE_PROP, oldValue, newValue);
272 }
273
274 /**
275 * The action to save a layer
276 *
277 */
278 public static class LayerSaveAction extends AbstractAction {
279 private Layer layer;
280 public LayerSaveAction(Layer layer) {
281 putValue(SMALL_ICON, ImageProvider.get("save"));
282 putValue(SHORT_DESCRIPTION, tr("Save the current data."));
283 putValue(NAME, tr("Save"));
284 setEnabled(true);
285 this.layer = layer;
286 }
287
288 public void actionPerformed(ActionEvent e) {
289 new SaveAction().doSave(layer);
290 }
291 }
292
293 public static class LayerSaveAsAction extends AbstractAction {
294 private Layer layer;
295 public LayerSaveAsAction(Layer layer) {
296 putValue(SMALL_ICON, ImageProvider.get("save_as"));
297 putValue(SHORT_DESCRIPTION, tr("Save the current data to a new file."));
298 putValue(NAME, tr("Save As..."));
299 setEnabled(true);
300 this.layer = layer;
301 }
302
303 public void actionPerformed(ActionEvent e) {
304 new SaveAsAction().doSave(layer);
305 }
306 }
307
308 public static class LayerGpxExportAction extends AbstractAction {
309 private Layer layer;
310 public LayerGpxExportAction(Layer layer) {
311 putValue(SMALL_ICON, ImageProvider.get("exportgpx"));
312 putValue(SHORT_DESCRIPTION, tr("Export the data to GPX file."));
313 putValue(NAME, tr("Export to GPX..."));
314 setEnabled(true);
315 this.layer = layer;
316 }
317
318 public void actionPerformed(ActionEvent e) {
319 new GpxExportAction().export(layer);
320 }
321 }
322}
Note: See TracBrowser for help on using the repository browser.