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

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

sonar - squid:S3052 - Fields should not be initialized to default values

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