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

Last change on this file since 2025 was 2025, checked in by Gubaer, 15 years ago

new: improved dialog for uploading/saving modified layers on exit
new: improved dialog for uploading/saving modified layers if layers are deleted
new: new progress monitor which can delegate rendering to any Swing component
more setters/getters for properties in OSM data classes (fields are @deprecated); started to update references in the code base

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