001: package net.sourceforge.squirrel_sql.client.gui.mainframe;
002:
003: /*
004: * Copyright (C) 2001-2004 Colin Bell
005: * colbell@users.sourceforge.net
006: *
007: * Modifications Copyright (C) 2003-2004 Jason Height
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
022: */
023: import java.awt.Dimension;
024: import java.awt.event.ActionEvent;
025: import java.awt.event.ActionListener;
026: import java.util.Iterator;
027:
028: import javax.swing.JComboBox;
029: import javax.swing.JLabel;
030:
031: import net.sourceforge.squirrel_sql.client.IApplication;
032: import net.sourceforge.squirrel_sql.client.action.ActionCollection;
033: import net.sourceforge.squirrel_sql.client.gui.db.SQLAlias;
034: import net.sourceforge.squirrel_sql.client.mainframe.action.CascadeAction;
035: import net.sourceforge.squirrel_sql.client.mainframe.action.ConnectToAliasCommand;
036: import net.sourceforge.squirrel_sql.client.mainframe.action.GlobalPreferencesAction;
037: import net.sourceforge.squirrel_sql.client.mainframe.action.MaximizeAction;
038: import net.sourceforge.squirrel_sql.client.mainframe.action.NewSessionPropertiesAction;
039: import net.sourceforge.squirrel_sql.client.mainframe.action.TileAction;
040: import net.sourceforge.squirrel_sql.client.mainframe.action.TileHorizontalAction;
041: import net.sourceforge.squirrel_sql.client.mainframe.action.TileVerticalAction;
042: import net.sourceforge.squirrel_sql.client.session.ISession;
043: import net.sourceforge.squirrel_sql.client.session.SessionManager;
044: import net.sourceforge.squirrel_sql.client.session.action.CommitAction;
045: import net.sourceforge.squirrel_sql.client.session.action.NewObjectTreeAction;
046: import net.sourceforge.squirrel_sql.client.session.action.NewSQLWorksheetAction;
047: import net.sourceforge.squirrel_sql.client.session.action.RollbackAction;
048: import net.sourceforge.squirrel_sql.client.session.action.ToggleAutoCommitAction;
049: import net.sourceforge.squirrel_sql.client.session.event.SessionAdapter;
050: import net.sourceforge.squirrel_sql.client.session.event.SessionEvent;
051: import net.sourceforge.squirrel_sql.fw.gui.GUIUtils;
052: import net.sourceforge.squirrel_sql.fw.gui.IToggleAction;
053: import net.sourceforge.squirrel_sql.fw.gui.SortedComboBoxModel;
054: import net.sourceforge.squirrel_sql.fw.gui.ToolBar;
055: import net.sourceforge.squirrel_sql.fw.sql.ISQLAlias;
056: import net.sourceforge.squirrel_sql.fw.util.IObjectCacheChangeListener;
057: import net.sourceforge.squirrel_sql.fw.util.ObjectCacheChangeEvent;
058: import net.sourceforge.squirrel_sql.fw.util.StringManager;
059: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
060:
061: /**
062: * Toolbar for <CODE>MainFrame</CODE>.
063: *
064: * @author <A HREF="mailto:colbell@users.sourceforge.net">Colin Bell</A>
065: */
066: class MainFrameToolBar extends ToolBar {
067: private static final long serialVersionUID = 1L;
068:
069: /** Internationalized strings for this class. */
070: private static final StringManager s_stringMgr = StringManagerFactory
071: .getStringManager(MainFrameToolBar.class);
072:
073: /** Application API. */
074: transient private IApplication _app;
075:
076: private boolean _dontReactToSessionDropDownAction = false;
077:
078: /**
079: * ctor.
080: *
081: * @param app Application API
082: *
083: * @throws IllegalArgumentException
084: * <TT>null</TT> <TT>IApplication</TT> or <TT>MainFrame</TT>
085: * passed.
086: */
087: MainFrameToolBar(IApplication app) {
088: super ();
089: if (app == null) {
090: throw new IllegalArgumentException("IApplication == null");
091: }
092: _app = app;
093: setUseRolloverButtons(true);
094: setFloatable(true);
095:
096: ActionCollection actions = _app.getActionCollection();
097: JLabel lbl = new JLabel(s_stringMgr
098: .getString("MainFrameToolBar.connectTo"));
099: lbl.setAlignmentY(0.5f);
100: add(lbl);
101: AliasesDropDown drop = new AliasesDropDown(app);
102: drop.setAlignmentY(0.5f);
103: add(drop);
104: addSeparator();
105: add(actions.get(GlobalPreferencesAction.class));
106: add(actions.get(NewSessionPropertiesAction.class));
107: addSeparator();
108: add(actions.get(TileAction.class));
109: add(actions.get(TileHorizontalAction.class));
110: add(actions.get(TileVerticalAction.class));
111: add(actions.get(CascadeAction.class));
112: add(actions.get(MaximizeAction.class));
113:
114: addSeparator();
115: JLabel lbl2 = new JLabel(" "
116: + s_stringMgr
117: .getString("MainFrameToolBar.activeSession")
118: + " ");
119: lbl.setAlignmentY(0.5f);
120: add(lbl2);
121: SessionDropDown sessionDropDown = new SessionDropDown(app);
122: sessionDropDown.setAlignmentY(0.5f);
123: add(sessionDropDown);
124:
125: addToggleAction((IToggleAction) actions
126: .get(ToggleAutoCommitAction.class));
127: add(actions.get(CommitAction.class));
128: add(actions.get(RollbackAction.class));
129:
130: addSeparator();
131:
132: add(actions.get(NewSQLWorksheetAction.class));
133: add(actions.get(NewObjectTreeAction.class));
134: }
135:
136: /**
137: * Dropdown holding all the current <TT>ISQLAlias</TT> objects. When one is
138: * selected the user will be prompted to connect to it.
139: */
140: private static class AliasesDropDown extends JComboBox implements
141: ActionListener {
142: private static final long serialVersionUID = 1L;
143:
144: transient final private IApplication _myApp;
145:
146: AliasesDropDown(IApplication app) {
147: super ();
148: _myApp = app;
149: final AliasesDropDownModel model = new AliasesDropDownModel(
150: app, this );
151: setModel(model);
152:
153: // Under JDK1.4 the first item in a JComboBox
154: // is no longer automatically selected.
155: if (getModel().getSize() > 0) {
156: setSelectedIndex(0);
157: }
158:
159: // Under JDK1.4 an empty JComboBox has an almost zero width.
160: else {
161: final Dimension dm = getPreferredSize();
162: dm.width = 100;
163: setPreferredSize(dm);
164: }
165: addActionListener(this );
166: setMaximumSize(getPreferredSize());
167:
168: app.getDataCache().addAliasesListener(
169: new MyAliasesListener(model, this ));
170: }
171:
172: /**
173: * An alias has been selected in the list so attempt to connect to it.
174: *
175: * @param evt Describes the event that has just occured.
176: */
177: public void actionPerformed(ActionEvent evt) {
178: try {
179: Object obj = getSelectedItem();
180: if (obj instanceof SQLAlias && this .isEnabled()) {
181: new ConnectToAliasCommand(_myApp, (SQLAlias) obj)
182: .execute();
183: }
184: } finally {
185: if (getModel().getSize() > 0) {
186: setSelectedIndex(0);
187: }
188: }
189: }
190: }
191:
192: /**
193: * Data model for AliasesDropDown.
194: */
195: private static class AliasesDropDownModel extends
196: SortedComboBoxModel {
197: private static final long serialVersionUID = 1L;
198:
199: transient private IApplication _myApp;
200: private AliasesDropDown _aliasDropDown;
201:
202: /**
203: * Default ctor. Listen to the <TT>DataCache</TT> object for additions
204: * and removals of aliases from the cache.
205: */
206: public AliasesDropDownModel(IApplication app,
207: AliasesDropDown drop) {
208: super ();
209: _myApp = app;
210: _aliasDropDown = drop;
211: load();
212: //_app.getDataCache().addAliasesListener(new MyAliasesListener(this));
213: }
214:
215: /**
216: * Load from <TT>DataCache</TT>.
217: */
218: private void load() {
219: Iterator<ISQLAlias> it = _myApp.getDataCache().aliases();
220: while (it.hasNext()) {
221: addAlias(it.next());
222: }
223: }
224:
225: /**
226: * Add an <TT>ISQLAlias</TT> to this model.
227: *
228: * @param alias <TT>ISQLAlias</TT> to be added.
229: */
230: private void addAlias(ISQLAlias alias) {
231: _aliasDropDown.setEnabled(false);
232: addElement(alias);
233: if (_aliasDropDown.getModel().getSize() > 0) {
234: _aliasDropDown.setSelectedIndex(0);
235: }
236: _aliasDropDown.setEnabled(true);
237: }
238:
239: /**
240: * Remove an <TT>ISQLAlias</TT> from this model.
241: *
242: * @param alias <TT>ISQLAlias</TT> to be removed.
243: */
244: private void removeAlias(ISQLAlias alias) {
245: _aliasDropDown.setEnabled(false);
246: removeElement(alias);
247: if (_aliasDropDown.getModel().getSize() > 0) {
248: _aliasDropDown.setSelectedIndex(0);
249: }
250: _aliasDropDown.setEnabled(true);
251: }
252: }
253:
254: /**
255: * Listener to changes in <TT>ObjectCache</TT>. As aliases are
256: * added to/removed from <TT>DataCache</TT> this model is updated.
257: */
258: private static class MyAliasesListener implements
259: IObjectCacheChangeListener {
260: /** Model that is listening. */
261: private AliasesDropDownModel _model;
262:
263: /** Control for _model. */
264: private AliasesDropDown _control;
265:
266: /**
267: * Ctor specifying the model and control that is listening.
268: */
269: MyAliasesListener(AliasesDropDownModel model,
270: AliasesDropDown control) {
271: super ();
272: _model = model;
273: _control = control;
274: }
275:
276: /**
277: * An alias has been added to the cache.
278: *
279: * @param evt Describes the event in the cache.
280: */
281: public void objectAdded(ObjectCacheChangeEvent evt) {
282: Object obj = evt.getObject();
283: if (obj instanceof ISQLAlias) {
284: _model.addAlias((ISQLAlias) obj);
285: }
286: if (_control.getItemCount() == 1) {
287: _control.setSelectedIndex(0);
288: }
289: }
290:
291: /**
292: * An alias has been removed from the cache.
293: *
294: * @param evt Describes the event in the cache.
295: */
296: public void objectRemoved(ObjectCacheChangeEvent evt) {
297: Object obj = evt.getObject();
298: if (obj instanceof ISQLAlias) {
299: _model.removeAlias((ISQLAlias) obj);
300: }
301: }
302: }
303:
304: /**
305: * Dropdown holding all the current active <TT>ISession</TT> objects.
306: */
307: private class SessionDropDown extends JComboBox implements
308: ActionListener {
309: private static final long serialVersionUID = 1L;
310: private IApplication _app;
311: private boolean _closing = false;
312:
313: SessionDropDown(IApplication app) {
314: super ();
315: _app = app;
316: final SessionManager sessionManager = _app
317: .getSessionManager();
318: final SessionDropDownModel model = new SessionDropDownModel(
319: sessionManager);
320: setModel(model);
321:
322: // Under JDK1.4 the first item in a JComboBox
323: // is no longer automatically selected.
324: if (getModel().getSize() > 0) {
325: setSelectedIndex(0);
326: } else {
327: // Under JDK1.4 an empty JComboBox has an almost zero width.
328: Dimension dm = getPreferredSize();
329: dm.width = 200;
330: setPreferredSize(dm);
331: // Dont enable the session drop down if it is empty
332: setEnabled(false);
333: }
334: addActionListener(this );
335: setMaximumSize(getPreferredSize());
336:
337: sessionManager.addSessionListener(new MySessionListener(
338: model, this ));
339: }
340:
341: /**
342: * An session has been selected in the list so set it as the active session.
343: *
344: * @param evt Describes the event that has just occured.
345: */
346: public void actionPerformed(ActionEvent evt) {
347: if (!_closing && !_dontReactToSessionDropDownAction) {
348: final Object obj = getSelectedItem();
349: if (obj instanceof ISession) {
350: _app.getSessionManager().setActiveSession(
351: (ISession) obj);
352: }
353: }
354: }
355: }
356:
357: /**
358: * Data model for SessionDropDownModel.
359: */
360: private static class SessionDropDownModel extends
361: SortedComboBoxModel {
362: private static final long serialVersionUID = 1L;
363: transient private SessionManager _sessionManager;
364:
365: /**
366: * Default ctor. Listen to the <TT>ISessioManager</TT> object for additions
367: * and removals of aliases from the cache.
368: */
369: public SessionDropDownModel(SessionManager sessionManager) {
370: super ();
371: _sessionManager = sessionManager;
372: load();
373: }
374:
375: /**
376: * Load from <TT>DataCache</TT>.
377: */
378: private void load() {
379: final ISession[] s = _sessionManager.getConnectedSessions();
380: if (s != null) {
381: for (int i = 0; i < s.length; i++) {
382: addSession(s[i]);
383: }
384: }
385: }
386:
387: /**
388: * Add an <TT>ISession</TT> to this model.
389: *
390: * @param session <TT>ISession</TT> to be added.
391: */
392: private void addSession(ISession session) {
393: addElement(session);
394: }
395:
396: /**
397: * Remove an <TT>ISession</TT> from this model.
398: *
399: * @param session <TT>ISession</TT> to be removed.
400: */
401: private void removeSession(ISession session) {
402: removeElement(session);
403: }
404: }
405:
406: /**
407: * Listener to changes in <TT>SessionManager</TT>. As sessions are
408: * added to/removed from <TT>SessionManager</TT> this model is updated.
409: */
410: private class MySessionListener extends SessionAdapter {
411: /** Model that is listening. */
412: private final SessionDropDownModel _model;
413:
414: /** Control for _model. */
415: private final SessionDropDown _sessionDropDown;
416:
417: /**
418: * Ctor specifying the model and control that is listening.
419: */
420: MySessionListener(SessionDropDownModel model,
421: SessionDropDown control) {
422: super ();
423: _model = model;
424: _sessionDropDown = control;
425: }
426:
427: public void sessionConnected(SessionEvent evt) {
428: final ISession session = evt.getSession();
429: // Needes to be done via event queque because method is not called from the event disptach thread.
430: GUIUtils.processOnSwingEventThread(new Runnable() {
431: public void run() {
432: _model.addSession(session);
433: _sessionDropDown.setEnabled(true);
434: }
435: });
436: }
437:
438: public void sessionClosing(SessionEvent evt) {
439: final ISession session = evt.getSession();
440: GUIUtils.processOnSwingEventThread(new Runnable() {
441: public void run() {
442: _sessionDropDown._closing = true;
443: _model.removeSession(session);
444: if (_model.getSize() == 0) {
445: _sessionDropDown.setEnabled(false);
446: }
447: _sessionDropDown._closing = false;
448: }
449: });
450:
451: }
452:
453: public void sessionActivated(SessionEvent evt) {
454: final ISession session = evt.getSession();
455:
456: // Needes to be done via event queque because adding the session to the
457: // drop down happens via the event queue too.
458: GUIUtils.processOnSwingEventThread(new Runnable() {
459: public void run() {
460: try {
461: _dontReactToSessionDropDownAction = true;
462: _sessionDropDown.setSelectedItem(session);
463: } finally {
464: _dontReactToSessionDropDownAction = false;
465: }
466: }
467: });
468: }
469:
470: }
471: }
|