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

Last change on this file since 8475 was 8384, checked in by Don-vip, 9 years ago

squid:S1244 - Floating point numbers should not be tested for equality

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