source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/server/OsmApiUrlInputPanel.java@ 9623

Last change on this file since 9623 was 9623, checked in by Don-vip, 8 years ago

fix transient/serializable findbugs warnings

  • Property svn:eol-style set to native
File size: 11.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.preferences.server;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Font;
7import java.awt.GridBagConstraints;
8import java.awt.GridBagLayout;
9import java.awt.Insets;
10import java.awt.event.ActionEvent;
11import java.awt.event.ActionListener;
12import java.awt.event.FocusAdapter;
13import java.awt.event.FocusEvent;
14import java.awt.event.ItemEvent;
15import java.awt.event.ItemListener;
16import java.net.MalformedURLException;
17import java.net.URL;
18import java.util.Arrays;
19
20import javax.swing.AbstractAction;
21import javax.swing.JCheckBox;
22import javax.swing.JComponent;
23import javax.swing.JLabel;
24import javax.swing.JPanel;
25import javax.swing.SwingUtilities;
26import javax.swing.event.DocumentEvent;
27import javax.swing.event.DocumentListener;
28import javax.swing.text.JTextComponent;
29
30import org.openstreetmap.josm.Main;
31import org.openstreetmap.josm.data.preferences.CollectionProperty;
32import org.openstreetmap.josm.gui.SideButton;
33import org.openstreetmap.josm.gui.help.HelpUtil;
34import org.openstreetmap.josm.gui.widgets.AbstractTextComponentValidator;
35import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
36import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
37import org.openstreetmap.josm.io.OsmApi;
38import org.openstreetmap.josm.tools.ImageProvider;
39import org.openstreetmap.josm.tools.Utils;
40
41/**
42 * Component allowing input os OSM API URL.
43 */
44public class OsmApiUrlInputPanel extends JPanel {
45
46 /**
47 * OSM API URL property key.
48 */
49 public static final String API_URL_PROP = OsmApiUrlInputPanel.class.getName() + ".apiUrl";
50
51 private JLabel lblValid;
52 private JLabel lblApiUrl;
53 private HistoryComboBox tfOsmServerUrl;
54 private transient ApiUrlValidator valOsmServerUrl;
55 private SideButton btnTest;
56 /** indicates whether to use the default OSM URL or not */
57 private JCheckBox cbUseDefaultServerUrl;
58 private final transient CollectionProperty SERVER_URL_HISTORY = new CollectionProperty("osm-server.url-history", Arrays.asList(
59 "http://api06.dev.openstreetmap.org/api", "http://master.apis.dev.openstreetmap.org/api"));
60
61 private transient ApiUrlPropagator propagator;
62
63 protected JComponent buildDefaultServerUrlPanel() {
64 cbUseDefaultServerUrl = new JCheckBox(tr("<html>Use the default OSM server URL (<strong>{0}</strong>)</html>", OsmApi.DEFAULT_API_URL));
65 cbUseDefaultServerUrl.addItemListener(new UseDefaultServerUrlChangeHandler());
66 cbUseDefaultServerUrl.setFont(cbUseDefaultServerUrl.getFont().deriveFont(Font.PLAIN));
67 return cbUseDefaultServerUrl;
68 }
69
70 protected final void build() {
71 setLayout(new GridBagLayout());
72 GridBagConstraints gc = new GridBagConstraints();
73
74 // the checkbox for the default UL
75 gc.fill = GridBagConstraints.HORIZONTAL;
76 gc.anchor = GridBagConstraints.NORTHWEST;
77 gc.weightx = 1.0;
78 gc.insets = new Insets(0, 0, 0, 0);
79 gc.gridwidth = 4;
80 add(buildDefaultServerUrlPanel(), gc);
81
82
83 // the input field for the URL
84 gc.gridx = 0;
85 gc.gridy = 1;
86 gc.gridwidth = 1;
87 gc.weightx = 0.0;
88 gc.insets = new Insets(0, 0, 0, 3);
89 add(lblApiUrl = new JLabel(tr("OSM Server URL:")), gc);
90
91 gc.gridx = 1;
92 gc.weightx = 1.0;
93 add(tfOsmServerUrl = new HistoryComboBox(), gc);
94 lblApiUrl.setLabelFor(tfOsmServerUrl);
95 SelectAllOnFocusGainedDecorator.decorate(tfOsmServerUrl.getEditorComponent());
96 valOsmServerUrl = new ApiUrlValidator(tfOsmServerUrl.getEditorComponent());
97 valOsmServerUrl.validate();
98 propagator = new ApiUrlPropagator();
99 tfOsmServerUrl.addActionListener(propagator);
100 tfOsmServerUrl.addFocusListener(propagator);
101
102 gc.gridx = 2;
103 gc.weightx = 0.0;
104 add(lblValid = new JLabel(), gc);
105
106 gc.gridx = 3;
107 gc.weightx = 0.0;
108 ValidateApiUrlAction actTest = new ValidateApiUrlAction();
109 tfOsmServerUrl.getEditorComponent().getDocument().addDocumentListener(actTest);
110 add(btnTest = new SideButton(actTest), gc);
111 }
112
113 /**
114 * Constructs a new {@code OsmApiUrlInputPanel}.
115 */
116 public OsmApiUrlInputPanel() {
117 build();
118 HelpUtil.setHelpContext(this, HelpUtil.ht("/Preferences/Connection#ApiUrl"));
119 }
120
121 /**
122 * Initializes the configuration panel with values from the preferences
123 */
124 public void initFromPreferences() {
125 String url = OsmApi.getOsmApi().getServerUrl();
126 if (OsmApi.DEFAULT_API_URL.equals(url.trim())) {
127 cbUseDefaultServerUrl.setSelected(true);
128 propagator.propagate(OsmApi.DEFAULT_API_URL);
129 } else {
130 cbUseDefaultServerUrl.setSelected(false);
131 tfOsmServerUrl.setText(url);
132 propagator.propagate(url);
133 }
134 tfOsmServerUrl.setPossibleItems(SERVER_URL_HISTORY.get());
135 }
136
137 /**
138 * Saves the values to the preferences
139 */
140 public void saveToPreferences() {
141 String oldUrl = OsmApi.getOsmApi().getServerUrl();
142 String hmiUrl = getStrippedApiUrl();
143 if (cbUseDefaultServerUrl.isSelected()) {
144 Main.pref.put("osm-server.url", null);
145 } else if (OsmApi.DEFAULT_API_URL.equals(hmiUrl)) {
146 Main.pref.put("osm-server.url", null);
147 } else {
148 Main.pref.put("osm-server.url", hmiUrl);
149 tfOsmServerUrl.addCurrentItemToHistory();
150 SERVER_URL_HISTORY.put(tfOsmServerUrl.getHistory());
151 }
152 String newUrl = OsmApi.getOsmApi().getServerUrl();
153
154 // When API URL changes, re-initialize API connection so we may adjust
155 // server-dependent settings.
156 if (!oldUrl.equals(newUrl)) {
157 try {
158 OsmApi.getOsmApi().initialize(null);
159 } catch (Exception x) {
160 Main.warn(x);
161 }
162 }
163 }
164
165 /**
166 * Returns the entered API URL, stripped of leading and trailing white characters.
167 * @return the entered API URL, stripped of leading and trailing white characters.
168 * May be an empty string if nothing has been entered. In this case, it means the user wants to use {@link OsmApi#DEFAULT_API_URL}.
169 * @see Utils#strip(String)
170 * @since 6602
171 */
172 public final String getStrippedApiUrl() {
173 return Utils.strip(tfOsmServerUrl.getText());
174 }
175
176 class ValidateApiUrlAction extends AbstractAction implements DocumentListener {
177 private String lastTestedUrl;
178
179 ValidateApiUrlAction() {
180 putValue(NAME, tr("Validate"));
181 putValue(SHORT_DESCRIPTION, tr("Test the API URL"));
182 updateEnabledState();
183 }
184
185 @Override
186 public void actionPerformed(ActionEvent arg0) {
187 final String url = getStrippedApiUrl();
188 final ApiUrlTestTask task = new ApiUrlTestTask(OsmApiUrlInputPanel.this, url);
189 Main.worker.submit(task);
190 Runnable r = new Runnable() {
191 @Override
192 public void run() {
193 if (task.isCanceled())
194 return;
195 Runnable r = new Runnable() {
196 @Override
197 public void run() {
198 if (task.isSuccess()) {
199 lblValid.setIcon(ImageProvider.get("dialogs", "valid"));
200 lblValid.setToolTipText(tr("The API URL is valid."));
201 lastTestedUrl = url;
202 updateEnabledState();
203 } else {
204 lblValid.setIcon(ImageProvider.get("warning-small"));
205 lblValid.setToolTipText(tr("Validation failed. The API URL seems to be invalid."));
206 }
207 }
208 };
209 SwingUtilities.invokeLater(r);
210 }
211 };
212 Main.worker.submit(r);
213 }
214
215 protected final void updateEnabledState() {
216 String url = getStrippedApiUrl();
217 boolean enabled = !url.isEmpty() && !url.equals(lastTestedUrl);
218 if (enabled) {
219 lblValid.setIcon(null);
220 }
221 setEnabled(enabled);
222 }
223
224 @Override
225 public void changedUpdate(DocumentEvent arg0) {
226 updateEnabledState();
227 }
228
229 @Override
230 public void insertUpdate(DocumentEvent arg0) {
231 updateEnabledState();
232 }
233
234 @Override
235 public void removeUpdate(DocumentEvent arg0) {
236 updateEnabledState();
237 }
238 }
239
240 /**
241 * Enables or disables the API URL input.
242 * @param enabled {@code true} to enable input, {@code false} otherwise
243 */
244 public void setApiUrlInputEnabled(boolean enabled) {
245 lblApiUrl.setEnabled(enabled);
246 tfOsmServerUrl.setEnabled(enabled);
247 lblValid.setEnabled(enabled);
248 btnTest.setEnabled(enabled);
249 }
250
251 private static class ApiUrlValidator extends AbstractTextComponentValidator {
252 ApiUrlValidator(JTextComponent tc) {
253 super(tc);
254 }
255
256 @Override
257 public boolean isValid() {
258 if (getComponent().getText().trim().isEmpty())
259 return false;
260
261 try {
262 new URL(getComponent().getText().trim());
263 return true;
264 } catch (MalformedURLException e) {
265 return false;
266 }
267 }
268
269 @Override
270 public void validate() {
271 if (getComponent().getText().trim().isEmpty()) {
272 feedbackInvalid(tr("OSM API URL must not be empty. Please enter the OSM API URL."));
273 return;
274 }
275 if (!isValid()) {
276 feedbackInvalid(tr("The current value is not a valid URL"));
277 } else {
278 feedbackValid(tr("Please enter the OSM API URL."));
279 }
280 }
281 }
282
283 /**
284 * Handles changes in the default URL
285 */
286 class UseDefaultServerUrlChangeHandler implements ItemListener {
287 @Override
288 public void itemStateChanged(ItemEvent e) {
289 switch(e.getStateChange()) {
290 case ItemEvent.SELECTED:
291 setApiUrlInputEnabled(false);
292 propagator.propagate(OsmApi.DEFAULT_API_URL);
293 break;
294 case ItemEvent.DESELECTED:
295 setApiUrlInputEnabled(true);
296 valOsmServerUrl.validate();
297 tfOsmServerUrl.requestFocusInWindow();
298 propagator.propagate();
299 break;
300 }
301 }
302 }
303
304 class ApiUrlPropagator extends FocusAdapter implements ActionListener {
305 public void propagate() {
306 propagate(getStrippedApiUrl());
307 }
308
309 public void propagate(String url) {
310 firePropertyChange(API_URL_PROP, null, url);
311 }
312
313 @Override
314 public void actionPerformed(ActionEvent e) {
315 propagate();
316 }
317
318 @Override
319 public void focusLost(FocusEvent arg0) {
320 propagate();
321 }
322 }
323}
Note: See TracBrowser for help on using the repository browser.