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

Last change on this file since 15845 was 14601, checked in by GerdP, 5 years ago

see #17040 dispose PreferenceDialog and call removeWindowListener()

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