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

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

see #15229 - deprecate all Main methods returning an URL

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