001: package net.sourceforge.squirrel_sql.client.preferences;
002:
003: /*
004: * Copyright (C) 2001-2004 Colin Bell
005: * colbell@users.sourceforge.net
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: import static net.sourceforge.squirrel_sql.client.preferences.PreferenceType.DATATYPE_PREFERENCES;
022: import static net.sourceforge.squirrel_sql.client.preferences.PreferenceType.GLOBAL_PREFERENCES;
023:
024: import java.awt.*;
025: import java.awt.event.ActionEvent;
026: import java.awt.event.ActionListener;
027: import java.awt.event.KeyEvent;
028: import java.util.ArrayList;
029: import java.util.Iterator;
030: import java.util.List;
031: import java.util.prefs.Preferences;
032:
033: import javax.swing.AbstractAction;
034: import javax.swing.BorderFactory;
035: import javax.swing.JButton;
036: import javax.swing.JComponent;
037: import javax.swing.JLabel;
038: import javax.swing.JPanel;
039: import javax.swing.JScrollPane;
040: import javax.swing.JTabbedPane;
041: import javax.swing.KeyStroke;
042:
043: import net.sourceforge.squirrel_sql.client.IApplication;
044: import net.sourceforge.squirrel_sql.client.gui.BaseInternalFrame;
045: import net.sourceforge.squirrel_sql.client.gui.builders.UIFactory;
046: import net.sourceforge.squirrel_sql.client.plugin.PluginInfo;
047: import net.sourceforge.squirrel_sql.fw.gui.CursorChanger;
048: import net.sourceforge.squirrel_sql.fw.gui.GUIUtils;
049: import net.sourceforge.squirrel_sql.fw.util.StringManager;
050: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
051: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
052: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
053:
054: /**
055: * This sheet allows the user to maintain global preferences.
056: * JASON: Rename to GlobalPreferencesInternalFrame
057: *
058: * @author <A HREF="mailto:colbell@users.sourceforge.net">Colin Bell</A>
059: */
060: @SuppressWarnings("serial")
061: public class GlobalPreferencesSheet extends BaseInternalFrame {
062: /** Internationalized strings for this class. */
063: private static final StringManager s_stringMgr = StringManagerFactory
064: .getStringManager(GlobalPreferencesSheet.class);
065:
066: /** Logger for this class. */
067: private final static ILogger s_log = LoggerController
068: .createLogger(GlobalPreferencesSheet.class);
069:
070: /** Singleton instance of this class. */
071: private static GlobalPreferencesSheet s_instance;
072:
073: /** Application API. */
074: private IApplication _app;
075:
076: /**
077: * List of all the panels (instances of
078: * <TT>IGlobalPreferencesPanel</TT> objects in shhet.
079: */
080: private List<IGlobalPreferencesPanel> _panels = new ArrayList<IGlobalPreferencesPanel>();
081:
082: private JTabbedPane _tabPane;
083:
084: /** Sheet title. */
085: private JLabel _titleLbl = new JLabel();
086:
087: public static final String PREF_KEY_GLOBAL_PREFS_SHEET_WIDTH = "Squirrel.globalPrefsSheetWidth";
088: public static final String PREF_KEY_GLOBAL_PREFS_SHEET_HEIGHT = "Squirrel.globalPrefsSheetHeight";
089:
090: /**
091: * Ctor specifying the application API.
092: *
093: * @param app Application API.
094: *
095: * @throws IllegalArgumentException
096: * Thrown if a <TT>null</TT> <TT>IApplication passed.
097: */
098: private GlobalPreferencesSheet(IApplication app) {
099: super (s_stringMgr.getString("GlobalPreferencesSheet.title"),
100: true);
101: if (app == null) {
102: throw new IllegalArgumentException("IApplication == null");
103: }
104:
105: _app = app;
106: createGUI();
107:
108: for (Iterator<IGlobalPreferencesPanel> it = _panels.iterator(); it
109: .hasNext();) {
110: IGlobalPreferencesPanel pnl = it.next();
111: try {
112: pnl.initialize(_app);
113: } catch (Throwable th) {
114: final String msg = s_stringMgr.getString(
115: "GlobalPreferencesSheet.error.loading", pnl
116: .getTitle());
117: s_log.error(msg, th);
118: _app.showErrorDialog(msg, th);
119: }
120: }
121: setSize(getDimension());
122:
123: app.getMainFrame().addInternalFrame(this , true, null);
124: GUIUtils.centerWithinDesktop(this );
125: setVisible(true);
126:
127: }
128:
129: private Dimension getDimension() {
130: return new Dimension(Preferences.userRoot().getInt(
131: PREF_KEY_GLOBAL_PREFS_SHEET_WIDTH, 650), Preferences
132: .userRoot().getInt(PREF_KEY_GLOBAL_PREFS_SHEET_HEIGHT,
133: 600));
134: }
135:
136: /**
137: * Show the Preferences dialog
138: *
139: * @param app Application API.
140: *
141: * @throws IllegalArgumentException
142: * Thrown if a <TT>null</TT> <TT>IApplication</TT> object passed.
143: */
144: @SuppressWarnings("unchecked")
145: public static synchronized void showSheet(IApplication app,
146: Class componentClassOfTabToSelect) {
147: if (s_instance == null) {
148: s_instance = new GlobalPreferencesSheet(app);
149: } else {
150: s_instance.moveToFront();
151: }
152:
153: if (null != componentClassOfTabToSelect) {
154: s_instance.selectTab(componentClassOfTabToSelect);
155: }
156: }
157:
158: @SuppressWarnings("unchecked")
159: private void selectTab(Class componentClassofTabToSelect) {
160: for (int i = 0; i < _tabPane.getTabCount(); i++) {
161: Component comp = _tabPane.getComponentAt(i);
162: if (JScrollPane.class.equals(comp.getClass())) {
163: comp = ((JScrollPane) comp).getViewport().getView();
164: }
165:
166: if (componentClassofTabToSelect.equals(comp.getClass())) {
167: _tabPane.setSelectedIndex(i);
168: return;
169: }
170: }
171: }
172:
173: public void dispose() {
174: Dimension size = getSize();
175: Preferences.userRoot().putInt(
176: PREF_KEY_GLOBAL_PREFS_SHEET_WIDTH, size.width);
177: Preferences.userRoot().putInt(
178: PREF_KEY_GLOBAL_PREFS_SHEET_HEIGHT, size.height);
179:
180: for (Iterator<IGlobalPreferencesPanel> it = _panels.iterator(); it
181: .hasNext();) {
182: IGlobalPreferencesPanel pnl = it.next();
183: pnl.uninitialize(_app);
184: }
185:
186: synchronized (getClass()) {
187: s_instance = null;
188: }
189: super .dispose();
190: }
191:
192: /**
193: * Set title of this frame. Ensure that the title label
194: * matches the frame title.
195: *
196: * @param title New title text.
197: */
198: public void setTitle(String title) {
199: super .setTitle(title);
200: _titleLbl.setText(title);
201: }
202:
203: /**
204: * Close this sheet.
205: */
206: private void performClose() {
207: dispose();
208: }
209:
210: /**
211: * OK button pressed so save changes.
212: */
213: private void performOk() {
214: CursorChanger cursorChg = new CursorChanger(_app.getMainFrame());
215: cursorChg.show();
216: try {
217: final boolean isDebug = s_log.isDebugEnabled();
218: long start = 0;
219: for (Iterator<IGlobalPreferencesPanel> it = _panels
220: .iterator(); it.hasNext();) {
221: if (isDebug) {
222: start = System.currentTimeMillis();
223: }
224: IGlobalPreferencesPanel pnl = it.next();
225: try {
226: pnl.applyChanges();
227: } catch (Throwable th) {
228: final String msg = s_stringMgr.getString(
229: "GlobalPreferencesSheet.error.saving", pnl
230: .getTitle());
231: s_log.error(msg, th);
232: _app.showErrorDialog(msg, th);
233: }
234: if (isDebug) {
235: s_log.debug("Panel " + pnl.getTitle()
236: + " applied changes in "
237: + (System.currentTimeMillis() - start)
238: + "ms");
239: }
240: }
241: } finally {
242: _app.savePreferences(GLOBAL_PREFERENCES);
243: _app.savePreferences(DATATYPE_PREFERENCES);
244: cursorChg.restore();
245: }
246:
247: dispose();
248: }
249:
250: /**
251: * Create user interface.
252: */
253: private void createGUI() {
254: setDefaultCloseOperation(DISPOSE_ON_CLOSE);
255:
256: // This is a tool window.
257: GUIUtils.makeToolWindow(this , true);
258:
259: // Add panels for core Squirrel functionality.
260: _panels.add(new GeneralPreferencesPanel());
261: _panels.add(new SQLPreferencesPanel(_app.getMainFrame()));
262: _panels.add(new ProxyPreferencesPanel());
263: _panels.add(new DataTypePreferencesPanel());
264:
265: // Go thru all loaded plugins asking for panels.
266: PluginInfo[] plugins = _app.getPluginManager()
267: .getPluginInformation();
268: for (int plugIdx = 0; plugIdx < plugins.length; ++plugIdx) {
269: PluginInfo pi = plugins[plugIdx];
270: if (pi.isLoaded()) {
271: IGlobalPreferencesPanel[] pnls = pi.getPlugin()
272: .getGlobalPreferencePanels();
273: if (pnls != null && pnls.length > 0) {
274: for (int pnlIdx = 0; pnlIdx < pnls.length; ++pnlIdx) {
275: _panels.add(pnls[pnlIdx]);
276: }
277: }
278: }
279: }
280:
281: // Add all panels to the tabbed pane.
282: _tabPane = UIFactory.getInstance().createTabbedPane();
283: for (Iterator<IGlobalPreferencesPanel> it = _panels.iterator(); it
284: .hasNext();) {
285: IGlobalPreferencesPanel pnl = it.next();
286: String pnlTitle = pnl.getTitle();
287: String hint = pnl.getHint();
288: _tabPane.addTab(pnlTitle, null, pnl.getPanelComponent(),
289: hint);
290: }
291:
292: // This seems to be necessary to get background colours
293: // correct. Without it labels added to the content pane
294: // have a dark background while those added to a JPanel
295: // in the content pane have a light background under
296: // the java look and feel. Similar effects occur for other
297: // look and feels.
298: final JPanel contentPane = new JPanel();
299: contentPane.setBorder(BorderFactory.createEmptyBorder(5, 10, 5,
300: 10));
301: setContentPane(contentPane);
302:
303: GridBagConstraints gbc = new GridBagConstraints();
304: contentPane.setLayout(new GridBagLayout());
305:
306: gbc.gridwidth = 1;
307: gbc.fill = GridBagConstraints.BOTH;
308:
309: gbc.gridx = 0;
310: gbc.gridy = 0;
311: gbc.weightx = 1;
312: contentPane.add(_titleLbl, gbc);
313:
314: ++gbc.gridy;
315: gbc.weighty = 1;
316: contentPane.add(_tabPane, gbc);
317:
318: ++gbc.gridy;
319: gbc.weighty = 0;
320: contentPane.add(createButtonsPanel(), gbc);
321:
322: AbstractAction closeAction = new AbstractAction() {
323: public void actionPerformed(ActionEvent actionEvent) {
324: performClose();
325: }
326: };
327: KeyStroke escapeStroke = KeyStroke.getKeyStroke(
328: KeyEvent.VK_ESCAPE, 0);
329: getRootPane().getInputMap(
330: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
331: escapeStroke, "CloseAction");
332: getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
333: .put(escapeStroke, "CloseAction");
334: getRootPane().getInputMap(JComponent.WHEN_FOCUSED).put(
335: escapeStroke, "CloseAction");
336: getRootPane().getActionMap().put("CloseAction", closeAction);
337:
338: }
339:
340: /**
341: * Create panel at bottom containing the buttons.
342: */
343: private JPanel createButtonsPanel() {
344: JPanel pnl = new JPanel();
345:
346: JButton okBtn = new JButton(s_stringMgr
347: .getString("GlobalPreferencesSheet.ok"));
348: okBtn.addActionListener(new ActionListener() {
349: public void actionPerformed(ActionEvent evt) {
350: performOk();
351: }
352: });
353: JButton closeBtn = new JButton(s_stringMgr
354: .getString("GlobalPreferencesSheet.close"));
355: closeBtn.addActionListener(new ActionListener() {
356: public void actionPerformed(ActionEvent evt) {
357: performClose();
358: }
359: });
360:
361: GUIUtils
362: .setJButtonSizesTheSame(new JButton[] { okBtn, closeBtn });
363:
364: pnl.add(okBtn);
365: pnl.add(closeBtn);
366:
367: getRootPane().setDefaultButton(okBtn);
368:
369: return pnl;
370: }
371: }
|