source: josm/trunk/src/org/openstreetmap/josm/gui/widgets/BoundingBoxSelectionPanel.java@ 3128

Last change on this file since 3128 was 3083, checked in by bastiK, 14 years ago

added svn:eol-style=native to source files

  • Property svn:eol-style set to native
File size: 9.5 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui.widgets;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Dimension;
7import java.awt.GridBagConstraints;
8import java.awt.GridBagLayout;
9import java.awt.Insets;
10import java.awt.Toolkit;
11import java.awt.datatransfer.DataFlavor;
12import java.awt.datatransfer.FlavorEvent;
13import java.awt.datatransfer.FlavorListener;
14import java.awt.datatransfer.Transferable;
15import java.awt.datatransfer.UnsupportedFlavorException;
16import java.awt.event.ActionEvent;
17import java.awt.event.MouseEvent;
18import java.io.IOException;
19
20import javax.swing.AbstractAction;
21import javax.swing.BorderFactory;
22import javax.swing.JLabel;
23import javax.swing.JPanel;
24import javax.swing.JPopupMenu;
25import javax.swing.JTextField;
26import javax.swing.event.DocumentEvent;
27import javax.swing.event.DocumentListener;
28import javax.swing.text.JTextComponent;
29
30import org.openstreetmap.josm.data.Bounds;
31import org.openstreetmap.josm.data.coor.CoordinateFormat;
32import org.openstreetmap.josm.data.coor.LatLon;
33import org.openstreetmap.josm.gui.JMultilineLabel;
34import org.openstreetmap.josm.tools.GBC;
35import org.openstreetmap.josm.tools.ImageProvider;
36import org.openstreetmap.josm.tools.OsmUrlToBounds;
37
38/**
39 *
40 *
41 */
42public class BoundingBoxSelectionPanel extends JPanel {
43
44 private JTextField[] tfLatLon = null;
45 private final JTextField tfOsmUrl = new JTextField();
46
47 protected void buildInputFields() {
48 tfLatLon = new JTextField[4];
49 for(int i=0; i< 4; i++) {
50 tfLatLon[i] = new JTextField(11);
51 tfLatLon[i].setMinimumSize(new Dimension(100,new JTextField().getMinimumSize().height));
52 SelectAllOnFocusGainedDecorator.decorate(tfLatLon[i]);
53 }
54 LatitudeValidator.decorate(tfLatLon[0]);
55 LatitudeValidator.decorate(tfLatLon[2]);
56 LongitudeValidator.decorate(tfLatLon[1]);
57 LongitudeValidator.decorate(tfLatLon[3]);
58 }
59
60 protected void build() {
61 buildInputFields();
62 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
63 setLayout(new GridBagLayout());
64 tfOsmUrl.getDocument().addDocumentListener(new OsmUrlRefresher());
65
66 // select content on receiving focus. this seems to be the default in the
67 // windows look+feel but not for others. needs invokeLater to avoid strange
68 // side effects that will cancel out the newly made selection otherwise.
69 tfOsmUrl.addFocusListener(new SelectAllOnFocusGainedDecorator());
70
71 add(new JLabel(tr("Min. latitude")), GBC.std().insets(0,0,3,5));
72 add(tfLatLon[0], GBC.std().insets(0,0,3,5));
73 add(new JLabel(tr("Min. longitude")), GBC.std().insets(0,0,3,5));
74 add(tfLatLon[1], GBC.eol());
75 add(new JLabel(tr("Max. latitude")), GBC.std().insets(0,0,3,5));
76 add(tfLatLon[2], GBC.std().insets(0,0,3,5));
77 add(new JLabel(tr("Max. longitude")), GBC.std().insets(0,0,3,5));
78 add(tfLatLon[3], GBC.eol());
79
80 GridBagConstraints gc = new GridBagConstraints();
81 gc.gridx = 0;
82 gc.gridy = 2;
83 gc.gridwidth = 4;
84 gc.fill = GridBagConstraints.HORIZONTAL;
85 gc.weightx = 1.0;
86 gc.insets = new Insets(10,0,0,3);
87 add(new JMultilineLabel(tr("URL from www.openstreetmap.org (you can paste a download URL here to specify a bounding box)")), gc);
88
89 gc.gridy = 3;
90 gc.insets = new Insets(3,0,0,3);
91 add(tfOsmUrl, gc);
92 tfOsmUrl.addMouseListener(new PopupMenuLauncher() {
93 @Override
94 public void launch(MouseEvent e) {
95 OsmUrlPopup popup = new OsmUrlPopup();
96 popup.show(tfOsmUrl, e.getX(), e.getY());
97 }
98 });
99 }
100
101 public BoundingBoxSelectionPanel() {
102 build();
103 }
104
105 public void setBoundingBox(Bounds area) {
106 updateBboxFields(area);
107 }
108
109 public Bounds getBoundingBox() {
110 double minlon, minlat, maxlon,maxlat;
111 try {
112 minlon = Double.parseDouble(tfLatLon[0].getText().trim());
113 minlat = Double.parseDouble(tfLatLon[1].getText().trim());
114 maxlon = Double.parseDouble(tfLatLon[2].getText().trim());
115 maxlat = Double.parseDouble(tfLatLon[3].getText().trim());
116 } catch(NumberFormatException e) {
117 return null;
118 }
119 if (!LatLon.isValidLon(minlon) || !LatLon.isValidLon(maxlon)
120 || !LatLon.isValidLat(minlat) || ! LatLon.isValidLat(maxlat))
121 return null;
122 if (minlon > maxlon)
123 return null;
124 if (minlat > maxlat)
125 return null;
126 return new Bounds(minlon,minlat,maxlon,maxlat);
127 }
128
129 private boolean parseURL() {
130 Bounds b = OsmUrlToBounds.parse(tfOsmUrl.getText());
131 if(b == null) return false;
132 updateBboxFields(b);
133 return true;
134 }
135
136 private void updateBboxFields(Bounds area) {
137 if (area == null) return;
138 tfLatLon[0].setText(area.getMin().latToString(CoordinateFormat.DECIMAL_DEGREES));
139 tfLatLon[1].setText(area.getMin().lonToString(CoordinateFormat.DECIMAL_DEGREES));
140 tfLatLon[2].setText(area.getMax().latToString(CoordinateFormat.DECIMAL_DEGREES));
141 tfLatLon[3].setText(area.getMax().lonToString(CoordinateFormat.DECIMAL_DEGREES));
142 }
143
144 static private class LatitudeValidator extends AbstractTextComponentValidator {
145
146 public static void decorate(JTextComponent tc) {
147 new LatitudeValidator(tc);
148 }
149
150 public LatitudeValidator(JTextComponent tc) {
151 super(tc);
152 }
153
154 @Override
155 public void validate() {
156 double value = 0;
157 try {
158 value = Double.parseDouble(getComponent().getText());
159 } catch(NumberFormatException ex) {
160 feedbackInvalid(tr("The string ''{0}'' is not a valid double value.", getComponent().getText()));
161 return;
162 }
163 if (!LatLon.isValidLat(value)) {
164 feedbackInvalid(tr("Value for latitude in range [-90,90] required.", getComponent().getText()));
165 return;
166 }
167 feedbackValid("");
168 }
169
170 @Override
171 public boolean isValid() {
172 double value = 0;
173 try {
174 value = Double.parseDouble(getComponent().getText());
175 } catch(NumberFormatException ex) {
176 return false;
177 }
178 if (!LatLon.isValidLat(value))
179 return false;
180 return true;
181 }
182 }
183
184 static private class LongitudeValidator extends AbstractTextComponentValidator{
185
186 public static void decorate(JTextComponent tc) {
187 new LongitudeValidator(tc);
188 }
189
190 public LongitudeValidator(JTextComponent tc) {
191 super(tc);
192 }
193
194 @Override
195 public void validate() {
196 double value = 0;
197 try {
198 value = Double.parseDouble(getComponent().getText());
199 } catch(NumberFormatException ex) {
200 feedbackInvalid(tr("The string ''{0}'' is not a valid double value.", getComponent().getText()));
201 return;
202 }
203 if (!LatLon.isValidLon(value)) {
204 feedbackInvalid(tr("Value for longitude in range [-180,180] required.", getComponent().getText()));
205 return;
206 }
207 feedbackValid("");
208 }
209
210 @Override
211 public boolean isValid() {
212 double value = 0;
213 try {
214 value = Double.parseDouble(getComponent().getText());
215 } catch(NumberFormatException ex) {
216 return false;
217 }
218 if (!LatLon.isValidLon(value))
219 return false;
220 return true;
221 }
222 }
223
224 class OsmUrlRefresher implements DocumentListener {
225 public void changedUpdate(DocumentEvent e) { parseURL(); }
226 public void insertUpdate(DocumentEvent e) { parseURL(); }
227 public void removeUpdate(DocumentEvent e) { parseURL(); }
228 }
229
230 class PasteUrlAction extends AbstractAction implements FlavorListener {
231
232 public PasteUrlAction() {
233 putValue(NAME, tr("Paste"));
234 putValue(SMALL_ICON, ImageProvider.get("paste"));
235 putValue(SHORT_DESCRIPTION, tr("Paste URL from clipboard"));
236 Toolkit.getDefaultToolkit().getSystemClipboard().addFlavorListener(this);
237 }
238
239 protected String getClipboardContent() {
240 Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
241 try {
242 if (t != null && t.isDataFlavorSupported(DataFlavor.stringFlavor)) {
243 String text = (String)t.getTransferData(DataFlavor.stringFlavor);
244 return text;
245 }
246 } catch (UnsupportedFlavorException ex) {
247 ex.printStackTrace();
248 return null;
249 } catch (IOException ex) {
250 ex.printStackTrace();
251 return null;
252 }
253 return null;
254 }
255
256 public void actionPerformed(ActionEvent e) {
257 String content = getClipboardContent();
258 if (content != null) {
259 tfOsmUrl.setText(content);
260 }
261 }
262
263 protected void updateEnabledState() {
264 setEnabled(getClipboardContent() != null);
265 }
266
267 public void flavorsChanged(FlavorEvent e) {
268 updateEnabledState();
269 }
270 }
271
272 class OsmUrlPopup extends JPopupMenu {
273 public OsmUrlPopup() {
274 add(new PasteUrlAction());
275 }
276 }
277}
Note: See TracBrowser for help on using the repository browser.