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

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

checkstyle - enable CatchParameterName rule

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