source: josm/trunk/src/org/openstreetmap/josm/gui/history/CoordinateInfoViewer.java@ 5050

Last change on this file since 5050 was 4990, checked in by Don-vip, 12 years ago

fix #7161 - Show distance of moved node in history window

  • Property svn:eol-style set to native
File size: 11.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.history;
3import static org.openstreetmap.josm.tools.I18n.tr;
4
5import java.awt.Color;
6import java.awt.GridBagConstraints;
7import java.awt.GridBagLayout;
8import java.awt.Insets;
9import java.util.Observable;
10import java.util.Observer;
11
12import javax.swing.BorderFactory;
13import javax.swing.JLabel;
14import javax.swing.JPanel;
15
16import org.openstreetmap.josm.data.coor.CoordinateFormat;
17import org.openstreetmap.josm.data.osm.history.HistoryNode;
18import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
19import org.openstreetmap.josm.gui.NavigatableComponent;
20import org.openstreetmap.josm.tools.CheckParameterUtil;
21
22/**
23 * An UI widget for displaying differences in the coordinates of two
24 * {@see HistoryNode}s.
25 *
26 */
27public class CoordinateInfoViewer extends JPanel {
28
29 /** background color used when the coordinates are different */
30 public final static Color BGCOLOR_DIFFERENCE = new Color(255,197,197);
31
32 /** the model */
33 private HistoryBrowserModel model;
34 /** the common info panel for the history node in role REFERENCE_POINT_IN_TIME */
35 private VersionInfoPanel referenceInfoPanel;
36 /** the common info panel for the history node in role CURRENT_POINT_IN_TIME */
37 private VersionInfoPanel currentInfoPanel;
38 /** the info panel for coordinates for the node in role REFERENCE_POINT_IN_TIME */
39 private LatLonViewer referenceLatLonViewer;
40 /** the info panel for coordinates for the node in role CURRENT_POINT_IN_TIME */
41 private LatLonViewer currentLatLonViewer;
42 /** the info panel for distance between the two coordinates */
43 private DistanceViewer distanceViewer;
44
45 protected void build() {
46 setLayout(new GridBagLayout());
47 GridBagConstraints gc = new GridBagConstraints();
48
49 // ---------------------------
50 gc.gridx = 0;
51 gc.gridy = 0;
52 gc.gridwidth = 1;
53 gc.gridheight = 1;
54 gc.weightx = 0.5;
55 gc.weighty = 0.0;
56 gc.insets = new Insets(5,5,5,0);
57 gc.fill = GridBagConstraints.HORIZONTAL;
58 gc.anchor = GridBagConstraints.FIRST_LINE_START;
59 referenceInfoPanel = new VersionInfoPanel(model, PointInTimeType.REFERENCE_POINT_IN_TIME);
60 add(referenceInfoPanel,gc);
61
62 gc.gridx = 1;
63 gc.gridy = 0;
64 gc.fill = GridBagConstraints.HORIZONTAL;
65 gc.weightx = 0.5;
66 gc.weighty = 0.0;
67 gc.anchor = GridBagConstraints.FIRST_LINE_START;
68 currentInfoPanel = new VersionInfoPanel(model, PointInTimeType.CURRENT_POINT_IN_TIME);
69 add(currentInfoPanel,gc);
70
71 // ---------------------------
72 // the two coordinate panels
73 gc.gridx = 0;
74 gc.gridy = 1;
75 gc.weightx = 0.5;
76 gc.weighty = 1.0;
77 gc.fill = GridBagConstraints.BOTH;
78 gc.anchor = GridBagConstraints.NORTHWEST;
79 add(referenceLatLonViewer = new LatLonViewer(model, PointInTimeType.REFERENCE_POINT_IN_TIME), gc);
80
81 gc.gridx = 1;
82 gc.gridy = 1;
83 gc.weightx = 0.5;
84 gc.weighty = 1.0;
85 gc.fill = GridBagConstraints.BOTH;
86 gc.anchor = GridBagConstraints.NORTHWEST;
87 add(currentLatLonViewer = new LatLonViewer(model, PointInTimeType.CURRENT_POINT_IN_TIME), gc);
88
89 // --------------------
90 // the distance panel
91 gc.gridx = 0;
92 gc.gridy = 2;
93 gc.gridwidth = 2;
94 gc.fill = GridBagConstraints.HORIZONTAL;
95 gc.weightx = 1.0;
96 gc.weighty = 0.0;
97 add(distanceViewer = new DistanceViewer(model), gc);
98 }
99
100 /**
101 *
102 * @param model the model. Must not be null.
103 * @throws IllegalArgumentException thrown if model is null
104 */
105 public CoordinateInfoViewer(HistoryBrowserModel model) throws IllegalArgumentException{
106 CheckParameterUtil.ensureParameterNotNull(model, "model");
107 setModel(model);
108 build();
109 registerAsObserver(model);
110 }
111
112 protected void unregisterAsObserver(HistoryBrowserModel model) {
113 if (currentInfoPanel != null) {
114 model.deleteObserver(currentInfoPanel);
115 }
116 if (referenceInfoPanel != null) {
117 model.deleteObserver(referenceInfoPanel);
118 }
119 if (currentLatLonViewer != null) {
120 model.deleteObserver(currentLatLonViewer);
121 }
122 if (referenceLatLonViewer != null) {
123 model.deleteObserver(referenceLatLonViewer);
124 }
125 if (distanceViewer != null) {
126 model.deleteObserver(distanceViewer);
127 }
128 }
129
130 protected void registerAsObserver(HistoryBrowserModel model) {
131 if (currentInfoPanel != null) {
132 model.addObserver(currentInfoPanel);
133 }
134 if (referenceInfoPanel != null) {
135 model.addObserver(referenceInfoPanel);
136 }
137 if (currentLatLonViewer != null) {
138 model.addObserver(currentLatLonViewer);
139 }
140 if (referenceLatLonViewer != null) {
141 model.addObserver(referenceLatLonViewer);
142 }
143 if (distanceViewer != null) {
144 model.addObserver(distanceViewer);
145 }
146 }
147
148 /**
149 * Sets the model for this viewer
150 *
151 * @param model the model.
152 */
153 public void setModel(HistoryBrowserModel model) {
154 if (this.model != null) {
155 unregisterAsObserver(model);
156 }
157 this.model = model;
158 if (this.model != null) {
159 registerAsObserver(model);
160 }
161 }
162
163 /**
164 * A UI widgets which displays the Lan/Lon-coordinates of a
165 * {@see HistoryNode}.
166 *
167 */
168 private static class LatLonViewer extends JPanel implements Observer{
169
170 private JLabel lblLat;
171 private JLabel lblLon;
172 private HistoryBrowserModel model;
173 private PointInTimeType role;
174
175 protected HistoryOsmPrimitive getPrimitive() {
176 if (model == null || role == null)
177 return null;
178 return model.getPointInTime(role);
179 }
180
181 protected HistoryOsmPrimitive getOppositePrimitive() {
182 if (model == null || role == null)
183 return null;
184 return model.getPointInTime(role.opposite());
185 }
186
187 protected void build() {
188 setLayout(new GridBagLayout());
189 setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
190 GridBagConstraints gc = new GridBagConstraints();
191
192 // --------
193 gc.gridx = 0;
194 gc.gridy = 0;
195 gc.fill = GridBagConstraints.NONE;
196 gc.weightx = 0.0;
197 gc.insets = new Insets(5,5,5,5);
198 gc.anchor = GridBagConstraints.NORTHWEST;
199 add(new JLabel(tr("Latitude: ")), gc);
200
201 // --------
202 gc.gridx = 1;
203 gc.gridy = 0;
204 gc.fill = GridBagConstraints.HORIZONTAL;
205 gc.weightx = 1.0;
206 add(lblLat = new JLabel(), gc);
207 lblLat.setBackground(Color.WHITE);
208 lblLat.setOpaque(true);
209 lblLat.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
210
211 // --------
212 gc.gridx = 0;
213 gc.gridy = 1;
214 gc.fill = GridBagConstraints.NONE;
215 gc.weightx = 0.0;
216 gc.anchor = GridBagConstraints.NORTHWEST;
217 add(new JLabel(tr("Longitude: ")), gc);
218
219 // --------
220 gc.gridx = 1;
221 gc.gridy = 1;
222 gc.fill = GridBagConstraints.HORIZONTAL;
223 gc.weightx = 1.0;
224 add(lblLon = new JLabel(), gc);
225 lblLon.setBackground(Color.WHITE);
226 lblLon.setOpaque(true);
227 lblLon.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
228
229 // fill the remaining space
230 gc.gridx = 0;
231 gc.gridy = 2;
232 gc.gridwidth = 2;
233 gc.fill = GridBagConstraints.BOTH;
234 gc.weightx = 1.0;
235 gc.weighty = 1.0;
236 add(new JPanel(), gc);
237 }
238
239 /**
240 *
241 * @param model a model
242 * @param role the role for this viewer.
243 */
244 public LatLonViewer(HistoryBrowserModel model, PointInTimeType role) {
245 build();
246 this.model = model;
247 this.role = role;
248 }
249
250 protected void refresh() {
251 HistoryOsmPrimitive p = getPrimitive();
252 HistoryOsmPrimitive opposite = getOppositePrimitive();
253 if (p == null || ! ( p instanceof HistoryNode)) return;
254 if (opposite == null || ! (opposite instanceof HistoryNode)) return;
255 HistoryNode node = (HistoryNode)p;
256 HistoryNode oppositeNode = (HistoryNode) opposite;
257
258 // display the coordinates
259 //
260 lblLat.setText(node.getCoords().latToString(CoordinateFormat.DECIMAL_DEGREES));
261 lblLon.setText(node.getCoords().lonToString(CoordinateFormat.DECIMAL_DEGREES));
262
263 // update background color to reflect differences in the coordinates
264 //
265 if (node.getCoords().lat() == oppositeNode.getCoords().lat()) {
266 lblLat.setBackground(Color.WHITE);
267 } else {
268 lblLat.setBackground(BGCOLOR_DIFFERENCE);
269 }
270 if (node.getCoords().lon() == oppositeNode.getCoords().lon()) {
271 lblLon.setBackground(Color.WHITE);
272 } else {
273 lblLon.setBackground(BGCOLOR_DIFFERENCE);
274 }
275
276 }
277
278 public void update(Observable o, Object arg) {
279 refresh();
280 }
281 }
282
283 private static class DistanceViewer extends LatLonViewer {
284
285 private JLabel lblDistance;
286
287 public DistanceViewer(HistoryBrowserModel model) {
288 super(model, PointInTimeType.REFERENCE_POINT_IN_TIME);
289 }
290
291 protected void build() {
292 setLayout(new GridBagLayout());
293 setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
294 GridBagConstraints gc = new GridBagConstraints();
295
296 // --------
297 gc.gridx = 0;
298 gc.gridy = 0;
299 gc.fill = GridBagConstraints.NONE;
300 gc.weightx = 0.0;
301 gc.insets = new Insets(5,5,5,5);
302 gc.anchor = GridBagConstraints.NORTHWEST;
303 add(new JLabel(tr("Distance: ")), gc);
304
305 // --------
306 gc.gridx = 1;
307 gc.gridy = 0;
308 gc.fill = GridBagConstraints.HORIZONTAL;
309 gc.weightx = 1.0;
310 add(lblDistance = new JLabel(), gc);
311 lblDistance.setBackground(Color.WHITE);
312 lblDistance.setOpaque(true);
313 lblDistance.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
314 }
315
316 protected void refresh() {
317 HistoryOsmPrimitive p = getPrimitive();
318 HistoryOsmPrimitive opposite = getOppositePrimitive();
319 if (p == null || ! ( p instanceof HistoryNode)) return;
320 if (opposite == null || ! (opposite instanceof HistoryNode)) return;
321 HistoryNode node = (HistoryNode) p;
322 HistoryNode oppositeNode = (HistoryNode) opposite;
323
324 // update distance
325 //
326 double distance = node.getCoords().greatCircleDistance(oppositeNode.getCoords());
327 if (distance > 0) {
328 lblDistance.setBackground(BGCOLOR_DIFFERENCE);
329 } else {
330 lblDistance.setBackground(Color.WHITE);
331 }
332 lblDistance.setText(NavigatableComponent.getDistText(distance));
333 }
334 }
335}
Note: See TracBrowser for help on using the repository browser.