source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceTabbedPane.java@ 3707

Last change on this file since 3707 was 3707, checked in by bastiK, 13 years ago

Added remotecontrol plugin to josm core. This plugin was initially written by Frederik Ramm (frederik) and incorporates code taken from YWMS plugin by frsantos. Major contributions by Bodo Meissner (bomm) and stephankn. Note: The code has been added, but is not "active" yet (RemoteControl.on == false). This is because wmsplugin and imagery plugin has not been adapted to this change. They are about to be integrated as well, so this adaption is not necessary.

  • Property svn:eol-style set to native
File size: 12.3 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui.preferences;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Font;
7import java.awt.GridBagLayout;
8import java.awt.ScrollPane;
9import java.awt.event.MouseWheelEvent;
10import java.awt.event.MouseWheelListener;
11import java.util.ArrayList;
12import java.util.Collection;
13import java.util.Iterator;
14import java.util.LinkedList;
15import java.util.List;
16import java.util.logging.Logger;
17
18import javax.swing.BorderFactory;
19import javax.swing.JComponent;
20import javax.swing.JLabel;
21import javax.swing.JOptionPane;
22import javax.swing.JPanel;
23import javax.swing.JScrollPane;
24import javax.swing.JTabbedPane;
25import javax.swing.SwingUtilities;
26
27import org.openstreetmap.josm.Main;
28import org.openstreetmap.josm.io.remotecontrol.RemoteControl;
29import org.openstreetmap.josm.plugins.PluginDownloadTask;
30import org.openstreetmap.josm.plugins.PluginHandler;
31import org.openstreetmap.josm.plugins.PluginInformation;
32import org.openstreetmap.josm.tools.BugReportExceptionHandler;
33import org.openstreetmap.josm.tools.GBC;
34import org.openstreetmap.josm.tools.I18n;
35import org.openstreetmap.josm.tools.ImageProvider;
36
37/**
38 * The preference settings.
39 *
40 * @author imi
41 */
42public class PreferenceTabbedPane extends JTabbedPane implements MouseWheelListener {
43 @SuppressWarnings("unused")
44 static private final Logger logger = Logger.getLogger(PreferenceTabbedPane.class.getName());
45
46 /**
47 * Allows PreferenceSettings to do validation of entered values when ok was pressed.
48 * If data is invalid then event can return false to cancel closing of preferences dialog.
49 *
50 */
51 public interface ValidationListener {
52 /**
53 *
54 * @return True if preferences can be saved
55 */
56 boolean validatePreferences();
57 }
58
59 private final static Collection<PreferenceSettingFactory> settingsFactory = new LinkedList<PreferenceSettingFactory>();
60 private final List<PreferenceSetting> settings = new ArrayList<PreferenceSetting>();
61
62 // some common tabs
63 public final JPanel display = createPreferenceTab("display", tr("Display Settings"), tr("Various settings that influence the visual representation of the whole program."));
64 public final JPanel connection = createPreferenceTab("connection", I18n.tr("Connection Settings"), I18n.tr("Connection Settings for the OSM server."),false);
65 public final JPanel map = createPreferenceTab("map", I18n.tr("Map Settings"), I18n.tr("Settings for the map projection and data interpretation."));
66 public final JPanel audio = createPreferenceTab("audio", I18n.tr("Audio Settings"), I18n.tr("Settings for the audio player and audio markers."));
67 public final JPanel plugins = createPreferenceTab("plugin", tr("Plugins"), tr("Configure available plugins."), false);
68
69 public final javax.swing.JTabbedPane displaycontent = new javax.swing.JTabbedPane();
70 public final javax.swing.JTabbedPane mapcontent = new javax.swing.JTabbedPane();
71
72 List<ValidationListener> validationListeners = new ArrayList<ValidationListener>();
73
74 /**
75 * Add validation listener to currently open preferences dialog. Calling to removeValidationListener is not necessary, all listeners will
76 * be automatically removed when dialog is closed
77 * @param validationListener
78 */
79 public void addValidationListener(ValidationListener validationListener) {
80 validationListeners.add(validationListener);
81 }
82
83 /**
84 * Construct a JPanel for the preference settings. Layout is GridBagLayout
85 * and a centered title label and the description are added. The panel
86 * will be shown inside a {@link ScrollPane}
87 * @param icon The name of the icon.
88 * @param title The title of this preference tab.
89 * @param desc A description in one sentence for this tab. Will be displayed
90 * italic under the title.
91 * @return The created panel ready to add other controls.
92 */
93 public JPanel createPreferenceTab(String icon, String title, String desc) {
94 return createPreferenceTab(icon, title, desc, false);
95 }
96
97 /**
98 * Construct a JPanel for the preference settings. Layout is GridBagLayout
99 * and a centered title label and the description are added.
100 * @param icon The name of the icon.
101 * @param title The title of this preference tab.
102 * @param desc A description in one sentence for this tab. Will be displayed
103 * italic under the title.
104 * @param inScrollPane if <code>true</code> the added tab will show scroll bars
105 * if the panel content is larger than the available space
106 * @return The created panel ready to add other controls.
107 */
108 public JPanel createPreferenceTab(String icon, String title, String desc, boolean inScrollPane) {
109 JPanel p = new JPanel(new GridBagLayout());
110 p.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
111 p.add(new JLabel(title), GBC.eol().insets(0,5,0,10).anchor(GBC.NORTHWEST));
112
113 JLabel descLabel = new JLabel("<html>"+desc+"</html>");
114 descLabel.setFont(descLabel.getFont().deriveFont(Font.ITALIC));
115 p.add(descLabel, GBC.eol().insets(5,0,5,20).fill(GBC.HORIZONTAL));
116
117 JComponent tab = p;
118 if (inScrollPane) {
119 JScrollPane sp = new JScrollPane(p);
120 tab = sp;
121 }
122 addTab(null, ImageProvider.get("preferences", icon), tab);
123 setToolTipTextAt(getTabCount()-1, "<html>"+desc+"</html>");
124 return p;
125 }
126
127 protected PluginPreference getPluginPreference() {
128 for (PreferenceSetting setting: settings) {
129 if (setting instanceof PluginPreference)
130 return (PluginPreference) setting;
131 }
132 return null;
133 }
134
135 public void savePreferences() {
136 if(Main.applet)
137 return;
138 // create a task for downloading plugins if the user has activated, yet not downloaded,
139 // new plugins
140 //
141 final PluginPreference preference = getPluginPreference();
142 final List<PluginInformation> toDownload = preference.getPluginsScheduledForUpdateOrDownload();
143 final PluginDownloadTask task;
144 if (! toDownload.isEmpty()) {
145 task = new PluginDownloadTask(this, toDownload, tr("Download plugins"));
146 } else {
147 task = null;
148 }
149
150 // this is the task which will run *after* the plugins are downloaded
151 //
152 final Runnable continuation = new Runnable() {
153 public void run() {
154 boolean requiresRestart = false;
155 if (task != null && !task.isCanceled()) {
156 if (!task.getDownloadedPlugins().isEmpty()) {
157 requiresRestart = true;
158 }
159 }
160
161 for (PreferenceSetting setting : settings) {
162 if (setting.ok()) {
163 requiresRestart = true;
164 }
165 }
166
167 // build the messages. We only display one message, including the status
168 // information from the plugin download task and - if necessary - a hint
169 // to restart JOSM
170 //
171 StringBuilder sb = new StringBuilder();
172 sb.append("<html>");
173 if (task != null && !task.isCanceled()) {
174 sb.append(PluginPreference.buildDownloadSummary(task));
175 }
176 if (requiresRestart) {
177 sb.append(tr("You have to restart JOSM for some settings to take effect."));
178 }
179 sb.append("</html>");
180
181 // display the message, if necessary
182 //
183 if ((task != null && !task.isCanceled()) || requiresRestart) {
184 JOptionPane.showMessageDialog(
185 Main.parent,
186 sb.toString(),
187 tr("Warning"),
188 JOptionPane.WARNING_MESSAGE
189 );
190 }
191 Main.parent.repaint();
192 }
193 };
194
195 if (task != null) {
196 // if we have to launch a plugin download task we do it asynchronously, followed
197 // by the remaining "save preferences" activites run on the Swing EDT.
198 //
199 Main.worker.submit(task);
200 Main.worker.submit(
201 new Runnable() {
202 public void run() {
203 SwingUtilities.invokeLater(continuation);
204 }
205 }
206 );
207 } else {
208 // no need for asynchronous activities. Simply run the remaining "save preference"
209 // activities on this thread (we are already on the Swing EDT
210 //
211 continuation.run();
212 }
213 }
214
215 /**
216 * If the dialog is closed with Ok, the preferences will be stored to the preferences-
217 * file, otherwise no change of the file happens.
218 */
219 public PreferenceTabbedPane() {
220 super(JTabbedPane.LEFT, JTabbedPane.SCROLL_TAB_LAYOUT);
221 super.addMouseWheelListener(this);
222 }
223
224 public void buildGui() {
225 for (PreferenceSettingFactory factory : settingsFactory) {
226 // logger.info("creating settings: " + factory);
227 PreferenceSetting setting = factory.createPreferenceSetting();
228 if (setting != null) {
229 settings.add(setting);
230 }
231 }
232
233 display.add(displaycontent, GBC.eol().fill(GBC.BOTH));
234 map.add(mapcontent, GBC.eol().fill(GBC.BOTH));
235 for (Iterator<PreferenceSetting> it = settings.iterator(); it.hasNext();) {
236 try {
237 PreferenceSetting settings = it.next();
238 //logger.info("adding gui: " + settings);
239 settings.addGui(this);
240 } catch (SecurityException e) {
241 it.remove();
242 } catch (Throwable e) {
243 /* allow to change most settings even if e.g. a plugin fails */
244 BugReportExceptionHandler.handleException(e);
245 }
246 }
247 }
248
249 public List<PreferenceSetting> getSettings() {
250 return settings;
251 }
252
253 @SuppressWarnings("unchecked")
254 public <T> T getSetting(Class<? extends T> clazz) {
255 for (PreferenceSetting setting:settings) {
256 if (clazz.isAssignableFrom(setting.getClass()))
257 return (T)setting;
258 }
259 return null;
260 }
261
262 static {
263 // order is important!
264 settingsFactory.add(new DrawingPreference.Factory());
265 settingsFactory.add(new ColorPreference.Factory());
266 settingsFactory.add(new LafPreference.Factory());
267 settingsFactory.add(new LanguagePreference.Factory());
268 settingsFactory.add(new ServerAccessPreference.Factory());
269 settingsFactory.add(new ProjectionPreference.Factory());
270 settingsFactory.add(new MapPaintPreference.Factory());
271 settingsFactory.add(new TaggingPresetPreference.Factory());
272 settingsFactory.add(new BackupPreference.Factory());
273 if(!Main.applet) {
274 settingsFactory.add(new PluginPreference.Factory());
275 }
276 settingsFactory.add(Main.toolbar);
277 settingsFactory.add(new AudioPreference.Factory());
278 settingsFactory.add(new ShortcutPreference.Factory());
279 settingsFactory.add(new ValidatorPreference.Factory());
280 if (RemoteControl.on) {
281 settingsFactory.add(new RemoteControlPreference.Factory());
282 }
283
284 PluginHandler.getPreferenceSetting(settingsFactory);
285
286 // always the last: advanced tab
287 settingsFactory.add(new AdvancedPreference.Factory());
288 }
289
290 /**
291 * This mouse wheel listener reacts when a scroll is carried out over the
292 * tab strip and scrolls one tab/down or up, selecting it immediately.
293 */
294 public void mouseWheelMoved(MouseWheelEvent wev) {
295 // Ensure the cursor is over the tab strip
296 if(super.indexAtLocation(wev.getPoint().x, wev.getPoint().y) < 0)
297 return;
298
299 // Get currently selected tab
300 int newTab = super.getSelectedIndex() + wev.getWheelRotation();
301
302 // Ensure the new tab index is sound
303 newTab = newTab < 0 ? 0 : newTab;
304 newTab = newTab >= super.getTabCount() ? super.getTabCount() - 1 : newTab;
305
306 // select new tab
307 super.setSelectedIndex(newTab);
308 }
309}
Note: See TracBrowser for help on using the repository browser.