source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceDialog.java

Last change on this file was 17265, checked in by GerdP, 4 years ago

see #7548: Re-organize the preference dialog
Apply 7548-no-empty.patch to avoid empty top panel

  • make sure that a panel is selected when selectPreviouslySelectedPreferences() is called and nothing was previously selected
  • reverts r17097
  • Property svn:eol-style set to native
File size: 8.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.preferences;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.BorderLayout;
7import java.awt.Component;
8import java.awt.Container;
9import java.awt.Dimension;
10import java.awt.FlowLayout;
11import java.awt.GridBagLayout;
12import java.awt.Insets;
13import java.awt.event.ActionEvent;
14import java.awt.event.WindowAdapter;
15import java.awt.event.WindowEvent;
16
17import javax.swing.AbstractAction;
18import javax.swing.BorderFactory;
19import javax.swing.JButton;
20import javax.swing.JCheckBox;
21import javax.swing.JDialog;
22import javax.swing.JPanel;
23
24import org.openstreetmap.josm.actions.ExpertToggleAction;
25import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
26import org.openstreetmap.josm.gui.help.HelpUtil;
27import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane.ValidationListener;
28import org.openstreetmap.josm.gui.util.GuiHelper;
29import org.openstreetmap.josm.gui.util.WindowGeometry;
30import org.openstreetmap.josm.tools.GBC;
31import org.openstreetmap.josm.tools.ImageProvider;
32import org.openstreetmap.josm.tools.InputMapUtils;
33import org.openstreetmap.josm.tools.Pair;
34
35/**
36 * The main preferences dialog.
37 *
38 * Dialog window where the user can change various settings. Organized in main
39 * tabs to the left ({@link TabPreferenceSetting}) and (optional) sub-pages
40 * ({@link SubPreferenceSetting}).
41 */
42public class PreferenceDialog extends JDialog {
43
44 private final PreferenceTabbedPane tpPreferences = new PreferenceTabbedPane();
45 private final ContextSensitiveHelpAction helpAction = new ContextSensitiveHelpAction();
46 private final WindowEventHandler windowEventHandler = new WindowEventHandler();
47 private boolean canceled;
48 private static Pair<Class<? extends TabPreferenceSetting>, Class<? extends SubPreferenceSetting>> previouslySelected;
49
50 /**
51 * Constructs a new {@code PreferenceDialog}.
52 * @param parent parent component
53 */
54 public PreferenceDialog(Component parent) {
55 super(GuiHelper.getFrameForComponent(parent), tr("Preferences"), ModalityType.DOCUMENT_MODAL);
56 build();
57 this.setMinimumSize(new Dimension(800, 600));
58 // set the maximum width to the current screen. If the dialog is opened on a
59 // smaller screen than before, this will reset the stored preference.
60 this.setMaximumSize(GuiHelper.getScreenSize());
61 }
62
63 protected JPanel buildActionPanel() {
64 JPanel pnl = new JPanel(new GridBagLayout());
65
66 JCheckBox expert = new JCheckBox(tr("Expert Mode"));
67 expert.setSelected(ExpertToggleAction.isExpert());
68 expert.addActionListener(e -> ExpertToggleAction.getInstance().actionPerformed(null));
69
70 JPanel btns = new JPanel(new FlowLayout(FlowLayout.CENTER));
71 btns.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
72 OKAction okAction = new OKAction();
73 btns.add(new JButton(okAction));
74 btns.add(new JButton(new CancelAction()));
75 btns.add(new JButton(helpAction));
76 pnl.add(expert, GBC.std().insets(5, 0, 0, 0));
77 pnl.add(btns, GBC.std().fill(GBC.HORIZONTAL));
78 InputMapUtils.addCtrlEnterAction(pnl, okAction);
79 return pnl;
80 }
81
82 protected final void build() {
83 Container c = getContentPane();
84 c.setLayout(new BorderLayout());
85 c.add(tpPreferences, BorderLayout.CENTER);
86 tpPreferences.buildGui();
87 tpPreferences.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
88 c.add(buildActionPanel(), BorderLayout.SOUTH);
89 addWindowListener(windowEventHandler);
90
91 InputMapUtils.addEscapeAction(getRootPane(), new CancelAction());
92 setHelpContext(HelpUtil.ht("/Action/Preferences"));
93 }
94
95 /**
96 * Sets the help context of the preferences dialog.
97 * @param helpContext new help context
98 * @since 13431
99 */
100 public final void setHelpContext(String helpContext) {
101 helpAction.setHelpTopic(helpContext);
102 HelpUtil.setHelpContext(getRootPane(), helpContext);
103 }
104
105 /**
106 * Replies the preferences tabbed pane.
107 * @return The preferences tabbed pane, or null if the dialog is not yet initialized.
108 * @since 5604
109 */
110 public PreferenceTabbedPane getTabbedPane() {
111 return tpPreferences;
112 }
113
114 /**
115 * Determines if preferences changes have been canceled.
116 * @return {@code true} if preferences changes have been canceled
117 */
118 public boolean isCanceled() {
119 return canceled;
120 }
121
122 protected void setCanceled(boolean canceled) {
123 this.canceled = canceled;
124 }
125
126 @Override
127 public void setVisible(boolean visible) {
128 if (visible) {
129 // Make the pref window at most as large as the parent JOSM window
130 // Have to take window decorations into account or the windows will be too large
131 Insets i = this.getParent().getInsets();
132 Dimension p = this.getParent().getSize();
133 p = new Dimension(Math.min(p.width-i.left-i.right, 700),
134 Math.min(p.height-i.top-i.bottom, 800));
135 new WindowGeometry(
136 getClass().getName() + ".geometry",
137 WindowGeometry.centerInWindow(
138 getParent(),
139 p
140 )
141 ).applySafe(this);
142 } else if (isShowing()) { // Avoid IllegalComponentStateException like in #8775
143 new WindowGeometry(this).remember(getClass().getName() + ".geometry");
144 }
145 super.setVisible(visible);
146 }
147
148 /**
149 * Select preferences tab that was selected previously.
150 */
151 public void selectPreviouslySelectedPreferences() {
152 if (previouslySelected != null && previouslySelected.b != null) {
153 tpPreferences.selectSubTabByPref(previouslySelected.b);
154 } else if (previouslySelected != null && previouslySelected.a != null) {
155 tpPreferences.selectTabByPref(previouslySelected.a);
156 } else {
157 tpPreferences.setSelectedIndex(0);
158 }
159 }
160
161 /**
162 * Select preferences tab by name.
163 * @param name preferences tab name (icon)
164 */
165 public void selectPreferencesTabByName(String name) {
166 tpPreferences.selectTabByName(name);
167 }
168
169 /**
170 * Select preferences tab by class.
171 * @param clazz preferences tab class
172 */
173 public void selectPreferencesTabByClass(Class<? extends TabPreferenceSetting> clazz) {
174 tpPreferences.selectTabByPref(clazz);
175 }
176
177 /**
178 * Select preferences sub-tab by class.
179 * @param clazz preferences sub-tab class
180 */
181 public void selectSubPreferencesTabByClass(Class<? extends SubPreferenceSetting> clazz) {
182 tpPreferences.selectSubTabByPref(clazz);
183 }
184
185 class CancelAction extends AbstractAction {
186 CancelAction() {
187 putValue(NAME, tr("Cancel"));
188 new ImageProvider("cancel").getResource().attachImageIcon(this);
189 putValue(SHORT_DESCRIPTION, tr("Close the preferences dialog and discard preference updates"));
190 }
191
192 public void cancel() {
193 setCanceled(true);
194 dispose();
195 }
196
197 @Override
198 public void actionPerformed(ActionEvent evt) {
199 cancel();
200 }
201 }
202
203 class OKAction extends AbstractAction {
204 OKAction() {
205 putValue(NAME, tr("OK"));
206 new ImageProvider("ok").getResource().attachImageIcon(this);
207 putValue(SHORT_DESCRIPTION, tr("Save the preferences and close the dialog"));
208 }
209
210 @Override
211 public void actionPerformed(ActionEvent evt) {
212 for (ValidationListener listener: tpPreferences.validationListeners) {
213 if (!listener.validatePreferences())
214 return;
215 }
216
217 tpPreferences.savePreferences();
218 setCanceled(false);
219 dispose();
220 }
221 }
222
223 class WindowEventHandler extends WindowAdapter {
224 @Override
225 public void windowClosing(WindowEvent arg0) {
226 new CancelAction().cancel();
227 }
228 }
229
230 @Override
231 public void dispose() {
232 previouslySelected = tpPreferences.getSelectedTab();
233 removeWindowListener(windowEventHandler);
234 setVisible(false); // save current geometry
235 super.dispose();
236 }
237}
Note: See TracBrowser for help on using the repository browser.