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

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

update: rewrite of layer dialog
new: allows multiple selection of layers in the dialog
new: move up, move down, toggle visibility, and delete on multiple layers
new: merge from an arbitrary layer into another layer, not only from the first into the second
new: new action for merging of the currently selected primitives on an arbitrary layer
new: make "active" layer explicit (special icon); activating a layer automatically moves it in the first position
refactoring: public fields 'name' and 'visible' on Layer are @deprecated. Use the setter/getters instead, Layer now emits PropertyChangeEvents if name or visibility are changed.

  • Property svn:eol-style set to native
File size: 8.7 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 private 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 * @deprecated use {@see #setVisible(boolean)} and {@see #isVisible()} instead. This field
69 * is going to be private (or protected) in a future release.
70 */
71 @Deprecated
72 public boolean visible = true;
73
74 /**
75 * The layer should be handled as a background layer in automatic handling
76 */
77 public boolean background = false;
78
79 /**
80 * The name of this layer.
81 *
82 * @deprecated use {@see #getName()} and {@see #setName(String)} instead. This field
83 * is going to be private (or protected) in the future.
84 */
85 @Deprecated
86 public String name;
87 /**
88 * If a file is associated with this layer, this variable should be set to it.
89 */
90 private File associatedFile;
91
92 /**
93 * Create the layer and fill in the necessary components.
94 */
95 public Layer(String name) {
96 this.propertyChangeSupport = new PropertyChangeSupport(this);
97 setName(name);
98 }
99
100 /**
101 * Paint the dataset using the engine set.
102 * @param mv The object that can translate GeoPoints to screen coordinates.
103 */
104 abstract public void paint(Graphics g, MapView mv);
105 /**
106 * Return a representative small image for this layer. The image must not
107 * be larger than 64 pixel in any dimension.
108 */
109 abstract public Icon getIcon();
110
111 /**
112 * @return A small tooltip hint about some statistics for this layer.
113 */
114 abstract public String getToolTipText();
115
116 /**
117 * Merges the given layer into this layer. Throws if the layer types are
118 * incompatible.
119 * @param from The layer that get merged into this one. After the merge,
120 * the other layer is not usable anymore and passing to one others
121 * mergeFrom should be one of the last things to do with a layer.
122 */
123 abstract public void mergeFrom(Layer from);
124
125 /**
126 * @param other The other layer that is tested to be mergable with this.
127 * @return Whether the other layer can be merged into this layer.
128 */
129 abstract public boolean isMergable(Layer other);
130
131 abstract public void visitBoundingBox(BoundingXYVisitor v);
132
133 abstract public Object getInfoComponent();
134
135 abstract public Component[] getMenuEntries();
136
137 /**
138 * Called, when the layer is removed from the mapview and is going to be
139 * destroyed.
140 *
141 * This is because the Layer constructor can not add itself safely as listener
142 * to the layerlist dialog, because there may be no such dialog yet (loaded
143 * via command line parameter).
144 */
145 public void destroy() {}
146
147 public File getAssociatedFile() { return associatedFile; }
148 public void setAssociatedFile(File file) { associatedFile = file; }
149
150
151 /**
152 * Replies the name of the layer
153 *
154 * @return the name of the layer
155 */
156 public String getName() {
157 return name;
158 }
159
160 /**
161 * Sets the name of the layer
162 *
163 *@param name the name. If null, the name is set to the empty string.
164 *
165 */
166 public void setName(String name) {
167 if (name == null) {
168 name = "";
169 }
170 String oldValue = this.name;
171 this.name = name;
172 if (!oldValue.equals(this.name)) {
173 propertyChangeSupport.firePropertyChange(NAME_PROP, oldValue, this.name);
174 }
175 }
176
177
178 public static class LayerSaveAction extends AbstractAction {
179 private Layer layer;
180 public LayerSaveAction(Layer layer) {
181 putValue(SMALL_ICON, ImageProvider.get("save"));
182 putValue(SHORT_DESCRIPTION, tr("Save the current data."));
183 putValue(NAME, tr("Save"));
184 setEnabled(true);
185 this.layer = layer;
186 }
187
188 public void actionPerformed(ActionEvent e) {
189 new SaveAction().doSave(layer);
190
191 }
192 }
193
194 public static class LayerSaveAsAction extends AbstractAction {
195 private Layer layer;
196 public LayerSaveAsAction(Layer layer) {
197 putValue(SMALL_ICON, ImageProvider.get("save_as"));
198 putValue(SHORT_DESCRIPTION, tr("Save the current data to a new file."));
199 putValue(NAME, tr("Save As..."));
200 setEnabled(true);
201 this.layer = layer;
202 }
203
204 public void actionPerformed(ActionEvent e) {
205 new SaveAsAction().doSave(layer);
206 }
207 }
208
209 public static class LayerGpxExportAction extends AbstractAction {
210 private Layer layer;
211 public LayerGpxExportAction(Layer layer) {
212 putValue(SMALL_ICON, ImageProvider.get("exportgpx"));
213 putValue(SHORT_DESCRIPTION, tr("Export the data to GPX file."));
214 putValue(NAME, tr("Export to GPX..."));
215 setEnabled(true);
216 this.layer = layer;
217 }
218
219 public void actionPerformed(ActionEvent e) {
220 new GpxExportAction().export(layer);
221 }
222 }
223
224 /**
225 * Sets the visibility of this layer. Emits property change event for
226 * property {@see #VISIBLE_PROP}.
227 *
228 * @param visible true, if the layer is visible; false, otherwise.
229 */
230 public void setVisible(boolean visible) {
231 boolean oldValue = this.visible;
232 this.visible = visible;
233 if (oldValue != this.visible) {
234 fireVisibleChanged(oldValue, this.visible);
235 }
236 }
237
238 /**
239 * Replies true if this layer is visible. False, otherwise.
240 * @return true if this layer is visible. False, otherwise.
241 */
242 public boolean isVisible() {
243 return visible;
244 }
245
246 /**
247 * Toggles the visibility state of this layer.
248 */
249 public void toggleVisible() {
250 setVisible(!isVisible());
251 }
252
253 /**
254 * Adds a {@see PropertyChangeListener}
255 *
256 * @param listener the listener
257 */
258 public void addPropertyChangeListener(PropertyChangeListener listener) {
259 propertyChangeSupport.addPropertyChangeListener(listener);
260 }
261
262 /**
263 * Removes a {@see PropertyChangeListener}
264 *
265 * @param listener the listener
266 */
267 public void removePropertyChangeListener(PropertyChangeListener listener) {
268 propertyChangeSupport.removePropertyChangeListener(listener);
269 }
270
271 /**
272 * fires a property change for the property {@see #VISIBLE_PROP}
273 *
274 * @param oldValue the old value
275 * @param newValue the new value
276 */
277 protected void fireVisibleChanged(boolean oldValue, boolean newValue) {
278 propertyChangeSupport.firePropertyChange(VISIBLE_PROP, oldValue, newValue);
279 }
280}
Note: See TracBrowser for help on using the repository browser.