source: josm/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java@ 223

Last change on this file since 223 was 223, checked in by imi, 17 years ago
  • fixed valid URL detection in MarkerLayer (removed com.sun.* stuff)
File size: 6.0 KB
Line 
1package org.openstreetmap.josm.gui.layer.markerlayer;
2
3import java.awt.Graphics;
4import java.awt.Point;
5import java.awt.event.ActionEvent;
6import java.awt.event.ActionListener;
7import java.io.File;
8import java.net.MalformedURLException;
9import java.net.URL;
10import java.util.HashMap;
11import java.util.LinkedList;
12import java.util.Map;
13
14import javax.swing.Icon;
15
16import org.openstreetmap.josm.Main;
17import org.openstreetmap.josm.data.coor.EastNorth;
18import org.openstreetmap.josm.data.coor.LatLon;
19import org.openstreetmap.josm.gui.MapView;
20import org.openstreetmap.josm.tools.ImageProvider;
21
22/**
23 * Basic marker class. Requires a position, and supports
24 * a custom icon and a name.
25 *
26 * This class is also used to create appropriate Marker-type objects
27 * when waypoints are imported.
28 *
29 * It hosts a public list object, named makers, containing implementations of
30 * the MarkerMaker interface. Whenever a Marker needs to be created, each
31 * object in makers is called with the waypoint parameters (Lat/Lon and tag
32 * data), and the first one to return a Marker object wins.
33 *
34 * By default, one the list contains one default "Maker" implementation that
35 * will create AudioMarkers for .wav files, ImageMarkers for .png/.jpg/.jpeg
36 * files, and WebMarkers for everything else. (The creation of a WebMarker will
37 * fail if there's no vaild URL in the <link> tag, so it might still make sense
38 * to add Makers for such waypoints at the end of the list.)
39 *
40 * The default implementation only looks at the value of the <link> tag inside
41 * the <wpt> tag of the GPX file.
42 *
43 * <h2>HowTo implement a new Marker</h2>
44 * <ul>
45 * <li> Subclass Marker or ButtonMarker and override <code>containsPoint</code>
46 * if you like to respond to user clicks</li>
47 * <li> Override paint, if you want a custom marker look (not "a label and a symbol")</li>
48 * <li> Implement MarkerCreator to return a new instance of your marker class</li>
49 * <li> In you plugin constructor, add an instance of your MarkerCreator
50 * implementation either on top or bottom of Marker.markerProducers.
51 * Add at top, if your marker should overwrite an current marker or at bottom
52 * if you only add a new marker style.</li>
53 * </ul>
54 *
55 * @author Frederik Ramm <frederik@remote.org>
56 */
57public class Marker implements ActionListener {
58
59 public final EastNorth eastNorth;
60 public final String text;
61 public final Icon symbol;
62
63 /**
64 * Plugins can add their Marker creation stuff at the bottom or top of this list
65 * (depending on whether they want to override default behaviour or just add new
66 * stuff).
67 */
68 public static LinkedList<MarkerProducers> markerProducers = new LinkedList<MarkerProducers>();
69
70 // Add one Maker specifying the default behaviour.
71 static {
72 Marker.markerProducers.add(new MarkerProducers() {
73 public Marker createMarker(LatLon ll, Map<String,String> data, File relativePath) {
74 String link = data.get("link");
75
76 // Try a relative file:// url, if the link is not in an URL-compatible form
77 if (relativePath != null && link != null && !isWellFormedAddress(link))
78 link = new File(relativePath, link).toURI().toString();
79
80 if (link == null)
81 return new Marker(ll, data.get("name"), data.get("symbol"));
82 if (link.endsWith(".wav"))
83 return AudioMarker.create(ll, link);
84 else if (link.endsWith(".png") || link.endsWith(".jpg") || link.endsWith(".jpeg") || link.endsWith(".gif"))
85 return ImageMarker.create(ll, link);
86 else
87 return WebMarker.create(ll, link);
88 }
89
90 private boolean isWellFormedAddress(String link) {
91 try {
92 new URL(link);
93 return true;
94 } catch (MalformedURLException x) {
95 return false;
96 }
97 }
98 });
99 }
100
101 public Marker(LatLon ll, String text, String iconName) {
102 eastNorth = Main.proj.latlon2eastNorth(ll);
103 this.text = text;
104 Icon symbol = ImageProvider.getIfAvailable("markers",iconName);
105 if (symbol == null)
106 symbol = ImageProvider.getIfAvailable("symbols",iconName);
107 if (symbol == null)
108 symbol = ImageProvider.getIfAvailable("nodes",iconName);
109 this.symbol = symbol;
110 }
111
112 /**
113 * Checks whether the marker display area contains the given point.
114 * Markers not interested in mouse clicks may always return false.
115 *
116 * @param p The point to check
117 * @return <code>true</code> if the marker "hotspot" contains the point.
118 */
119 public boolean containsPoint(Point p) {
120 return false;
121 }
122
123 /**
124 * Called when the mouse is clicked in the marker's hotspot. Never
125 * called for markers which always return false from containsPoint.
126 *
127 * @param ev A dummy ActionEvent
128 */
129 public void actionPerformed(ActionEvent ev) {
130 }
131
132 /**
133 * Paints the marker.
134 * @param g graphics context
135 * @param mv map view
136 * @param mousePressed true if the left mouse button is pressed
137 */
138 public void paint(Graphics g, MapView mv, boolean mousePressed, String show) {
139 Point screen = mv.getPoint(eastNorth);
140 if (symbol != null) {
141 symbol.paintIcon(mv, g, screen.x-symbol.getIconWidth()/2, screen.y-symbol.getIconHeight()/2);
142 } else {
143 g.drawLine(screen.x-2, screen.y-2, screen.x+2, screen.y+2);
144 g.drawLine(screen.x+2, screen.y-2, screen.x-2, screen.y+2);
145 }
146
147 if ((text != null) && (show.equalsIgnoreCase("show")))
148 g.drawString(text, screen.x+4, screen.y+2);
149 }
150
151 /**
152 * Returns an object of class Marker or one of its subclasses
153 * created from the parameters given.
154 *
155 * @param ll lat/lon for marker
156 * @param data hash containing keys and values from the GPX waypoint structure
157 * @param relativePath An path to use for constructing relative URLs or
158 * <code>null</code> for no relative URLs
159 * @return a new Marker object
160 */
161 public static Marker createMarker(LatLon ll, HashMap<String,String> data, File relativePath) {
162 for (MarkerProducers maker : Marker.markerProducers) {
163 Marker marker = maker.createMarker(ll, data, relativePath);
164 if (marker != null)
165 return marker;
166 }
167 return null;
168 }
169}
Note: See TracBrowser for help on using the repository browser.