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

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

see #15182 - deprecate all Main logging methods and introduce suitable replacements in Logging for most of them

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