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

Last change on this file since 12841 was 12841, checked in by bastiK, 7 years ago

see #15229 - fix deprecations caused by [12840]

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