KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > columba > core > gui > frame > FrameManager


1 // The contents of this file are subject to the Mozilla Public License Version
2
// 1.1
3
//(the "License"); you may not use this file except in compliance with the
4
//License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
5
//
6
//Software distributed under the License is distributed on an "AS IS" basis,
7
//WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
8
//for the specific language governing rights and
9
//limitations under the License.
10
//
11
//The Original Code is "The Columba Project"
12
//
13
//The Initial Developers of the Original Code are Frederik Dietz and Timo
14
// Stich.
15
//Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
16
//
17
//All Rights Reserved.
18

19 package org.columba.core.gui.frame;
20
21 import java.util.Enumeration JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.LinkedList JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.logging.Logger JavaDoc;
28
29 import javax.swing.JFrame JavaDoc;
30
31 import org.columba.api.gui.frame.IContainer;
32 import org.columba.api.gui.frame.IFrameManager;
33 import org.columba.api.gui.frame.IFrameMediator;
34 import org.columba.api.plugin.IExtension;
35 import org.columba.api.plugin.IExtensionHandler;
36 import org.columba.api.plugin.IExtensionHandlerKeys;
37 import org.columba.api.plugin.PluginException;
38 import org.columba.api.plugin.PluginHandlerNotFoundException;
39 import org.columba.api.plugin.PluginLoadingFailedException;
40 import org.columba.core.config.Config;
41 import org.columba.core.config.ViewItem;
42 import org.columba.core.logging.Logging;
43 import org.columba.core.plugin.PluginManager;
44 import org.columba.core.shutdown.ShutdownManager;
45 import org.columba.core.xml.XmlElement;
46
47 /**
48  * FrameManager manages all frames. It keeps a list of every controller. Its
49  * also the place to create a new frame, or save and close all frames at once.
50  *
51  * Frame controllers are plugins.
52  *
53  * @see FrameExtensionHandler
54  *
55  * @author fdietz
56  */

57 public class FrameManager implements IFrameManager {
58
59     private static final Logger JavaDoc LOG = Logger
60             .getLogger("org.columba.core.gui.frame");
61
62     /** list of frame controllers */
63     protected List JavaDoc activeFrameCtrls = new LinkedList JavaDoc();
64
65     /** viewlist xml treenode */
66     protected XmlElement viewList = Config.getInstance().get("views")
67             .getElement("/views/viewlist");
68
69     /** Default view specifications to be used when opening a new view */
70     protected XmlElement defaultViews = Config.getInstance().get("views")
71             .getElement("/views/defaultviews");
72
73     protected IExtensionHandler handler;
74
75     private static FrameManager instance = new FrameManager();
76
77     /**
78      * we cache instances for later re-use
79      */

80     protected Map JavaDoc frameMediatorCache;
81
82     /**
83      * Obtains a reference to the frame plugin handler and registers a shutdown
84      * hook with the ShutdownManager.
85      */

86     public FrameManager() {
87
88         frameMediatorCache = new HashMap JavaDoc();
89
90         // get plugin handler for handling frames
91
try {
92             handler = PluginManager.getInstance()
93                     .getExtensionHandler(IExtensionHandlerKeys.ORG_COLUMBA_CORE_FRAME);
94         } catch (PluginHandlerNotFoundException ex) {
95             throw new RuntimeException JavaDoc(ex);
96         }
97
98         // this is executed on shutdown: store all open frames so that they
99
// can be restored on the next start
100
ShutdownManager.getInstance().register(new Runnable JavaDoc() {
101             public void run() {
102                 storeViews();
103             }
104         });
105     }
106
107     public static FrameManager getInstance() {
108         return instance;
109     }
110
111     
112     /**
113      * Check if frame mediator with given id is a managed frame.
114      *
115      * @param frameMediatorId
116      * @return
117      */

118     public boolean isManaged(String JavaDoc frameMediatorId) {
119         Enumeration JavaDoc _enum = handler.getExtensionEnumeration();
120         while (_enum.hasMoreElements()) {
121             IExtension extension = (IExtension) _enum.nextElement();
122             String JavaDoc managed = extension.getMetadata().getAttribute("managed");
123             if (managed == null)
124                 managed = "false";
125
126             if ( (extension.getMetadata().getId().equals(frameMediatorId)) && managed.equals("true") ) return true;
127         }
128         
129         return false;
130     }
131     
132     /**
133      * Close all frames and re-open them again.
134      * <p>
135      * This is necessary when updating translations, adding new plugins which
136      * extend the menu and probably also look and feel changes.
137      *
138      */

139     public void refresh() {
140         storeViews();
141         openStoredViews();
142     }
143
144     /**
145      * Store all open frames so that they can be restored on next startup.
146      *
147      */

148     public void storeViews() {
149         // used to temporarily store the values while the original
150
// viewList gets modified by the close method
151
List JavaDoc newViewList = new LinkedList JavaDoc();
152
153         ViewItem v;
154
155         // we cannot use an iterator here because the close method
156
// manipulates the list
157
while (activeFrameCtrls.size() > 0) {
158             DefaultContainer c = (DefaultContainer) activeFrameCtrls.get(0);
159             v = c.getViewItem();
160
161             // store every open frame in our temporary list
162
newViewList.add(v.getRoot());
163
164             // close every open frame
165
c.close();
166         }
167
168         // if not we haven't actually closed a frame, leave viewList as is
169
if (newViewList.size() > 0) {
170             // the close method manipulates the viewList so we have to
171
// remove the existing element and fill in our temporarily
172
// stored ones
173
viewList.removeAllElements();
174
175             for (Iterator JavaDoc it = newViewList.iterator(); it.hasNext();) {
176                 viewList.addElement((XmlElement) it.next());
177             }
178         }
179     }
180
181     /**
182      * Opens all views stored in the configuration.
183      */

184     public void openStoredViews() {
185         // load all frames from configuration file
186
for (int i = 0; i < viewList.count(); i++) {
187             // get element from view list
188
XmlElement view = viewList.getElement(i);
189             try {
190                 createFrameMediator(new ViewItem(view));
191             } catch (PluginLoadingFailedException plfe) {
192                 // should not occur
193
continue;
194             }
195
196         }
197
198     }
199
200     /**
201      * Returns an array of all open frames.
202      */

203     public IContainer[] getOpenFrames() {
204         return (IContainer[]) activeFrameCtrls.toArray(new IContainer[0]);
205     }
206
207     /*
208      * (non-Javadoc)
209      *
210      * @see org.columba.core.gui.frame.IFrameManager#getActiveFrameMediator()
211      */

212     public IContainer getActiveFrameMediator() {
213         Iterator JavaDoc it = activeFrameCtrls.iterator();
214         while (it.hasNext()) {
215             IContainer m = (IContainer) it.next();
216             JFrame JavaDoc frame = m.getFrame();
217             if (frame.isActive())
218                 return m;
219         }
220
221         return null;
222     }
223
224     /**
225      * Get active/focused JFrame.
226      *
227      * @return active frame
228      */

229     public JFrame JavaDoc getActiveFrame() {
230         IContainer m = getActiveFrameMediator();
231         if (m != null)
232             return m.getFrame();
233
234         // fall-back
235
return new JFrame JavaDoc();
236     }
237
238     /**
239      * @param viewItem
240      * @param id
241      * @return
242      * @throws PluginLoadingFailedException
243      */

244     private IFrameMediator instanciateFrameMediator(ViewItem viewItem)
245             throws PluginLoadingFailedException {
246         String JavaDoc id = viewItem.get("id");
247
248         IFrameMediator frame = null;
249         if (frameMediatorCache.containsKey(id)) {
250             LOG.fine("use cached instance " + id);
251
252             // found cached instance
253
// -> re-use this instance and remove it from cache
254
frame = (IFrameMediator) frameMediatorCache.remove(id);
255         } else {
256             LOG.fine("create new instance " + id);
257             Object JavaDoc[] args = { viewItem };
258             // create new instance
259
// -> get frame controller using the plugin handler found above
260

261             try {
262                 IExtension extension = handler.getExtension(id);
263                 frame = (IFrameMediator) extension.instanciateExtension(args);
264             } catch (PluginException e) {
265                 LOG.severe(e.getMessage());
266                 if (Logging.DEBUG)
267                     // TODO Auto-generated catch block
268
e.printStackTrace();
269             }
270         }
271         return frame;
272     }
273
274     protected IFrameMediator createFrameMediator(ViewItem viewItem)
275             throws PluginLoadingFailedException {
276
277     
278
279         IFrameMediator frame = instanciateFrameMediator(viewItem);
280
281         IContainer c = new DefaultContainer((DefaultFrameController) frame);
282
283         activeFrameCtrls.add(c);
284
285         return frame;
286     }
287
288     /*
289      * (non-Javadoc)
290      *
291      * @see org.columba.core.gui.frame.IFrameManager#openView(java.lang.String)
292      */

293     public IFrameMediator openView(String JavaDoc id)
294             throws PluginLoadingFailedException {
295         // look for default view settings (if not found, null is returned)
296
ViewItem view = loadDefaultView(id);
297
298         if (view == null)
299             view = ViewItem.createDefault(id);
300
301         // Create a frame controller for this view
302
// view = null => defaults specified by frame controller is used
303
IFrameMediator controller = createFrameMediator(view);
304
305         return controller;
306     }
307
308     /*
309      * (non-Javadoc)
310      *
311      * @see org.columba.core.gui.frame.IFrameManager#switchView(org.columba.core.gui.frame.IContainer,
312      * java.lang.String)
313      */

314     public IFrameMediator switchView(IContainer c, String JavaDoc id)
315             throws PluginLoadingFailedException {
316         // look for default view settings (if not found, null is returned)
317
ViewItem view = loadDefaultView(id);
318
319         if (view == null)
320             view = ViewItem.createDefault(id);
321
322         // cancel, if we show already correct frame mediator
323
if ( c.getFrameMediator().getId().equals(id)) return c.getFrameMediator();
324         
325         // Create a frame controller for this view
326

327         // save old framemediator in cache (use containers's old id)
328
frameMediatorCache.put(((DefaultContainer) c).getViewItem().get("id"),
329                 c.getFrameMediator());
330
331         IFrameMediator frame = instanciateFrameMediator(view);
332
333         c.switchFrameMediator(frame);
334
335         return frame;
336     }
337
338     /**
339      * Gets default view settings for a given view type
340      *
341      * @param id
342      * id specifying view type
343      * @return View settings
344      */

345     protected ViewItem loadDefaultView(String JavaDoc id) {
346         // If defaultViews doesn't exist, create it (backward compatibility)
347
if (defaultViews == null) {
348             XmlElement gui = Config.getInstance().get("views").getElement(
349                     "/views");
350             defaultViews = new XmlElement("defaultviews");
351             gui.addElement(defaultViews);
352         }
353
354         // search through defaultViews to get settings for given id
355
ViewItem view = null;
356
357         for (int i = 0; i < defaultViews.count(); i++) {
358             XmlElement child = defaultViews.getElement(i);
359             String JavaDoc childId = child.getAttribute("id");
360
361             if ((childId != null) && childId.equals(id)) {
362                 view = new ViewItem(child);
363
364                 break;
365             }
366         }
367
368         return view;
369     }
370
371     /**
372      * Saves default view settings for given view type. These will be used as
373      * startup values next a view of this type is opened. Though, views opened
374      * at startup will use settings from viewlist instead.
375      *
376      * Only one set of settings are stored for each view id.
377      *
378      * @param view
379      * view settings to be stored
380      */

381     protected void saveDefaultView(ViewItem view) {
382         if (view == null) {
383             return; // nothing to save
384
}
385
386         String JavaDoc id = view.get("id");
387
388         // removed previous default values
389
ViewItem oldView = loadDefaultView(id);
390
391         if (oldView != null) {
392             defaultViews.removeElement(oldView.getRoot());
393         }
394
395         // store current view settings
396
defaultViews.addElement(view.getRoot());
397     }
398
399     /**
400      * Called when a frame is closed. The reference is removed from the list of
401      * active (shown) frames. If it's the last open view, the view settings are
402      * stored in the view list.
403      *
404      * @param c
405      * Reference to frame controller for the view which is closed
406      */

407     public void close(IContainer c) {
408
409         // Check if the frame controller has been registered, else do nothing
410
if (activeFrameCtrls.contains(c)) {
411             ViewItem v = ((DefaultContainer) c).getViewItem();
412
413             // save in cache
414
frameMediatorCache.put(v.get("id"), c.getFrameMediator());
415
416             saveDefaultView(v);
417             activeFrameCtrls.remove(c);
418
419             if (activeFrameCtrls.size() == 0) {
420                 // this is the last frame so store its data in the viewList
421
viewList.removeAllElements();
422                 viewList.addElement(v.getRoot());
423             }
424         }
425
426         if (activeFrameCtrls.size() == 0) {
427             // shutdown Columba if no frame exists anymore
428
if (getOpenFrames().length == 0) {
429
430                 ShutdownManager.getInstance().shutdown(0);
431             }
432         }
433     }
434
435     public ViewItem createCustomViewItem(String JavaDoc id) {
436         XmlElement parent = Config.getInstance().get("views").getElement(
437                 "views");
438         XmlElement custom = parent.getElement("custom");
439         if (custom == null)
440             custom = parent.addSubElement("custom");
441
442         for (int i = 0; i < custom.count(); i++) {
443             XmlElement child = custom.getElement(i);
444             String JavaDoc name = child.getAttribute("id");
445             if (name.equals(id))
446                 return new ViewItem(child);
447         }
448
449         ViewItem viewItem = ViewItem.createDefault(id);
450         custom.addElement(viewItem.getRoot());
451
452         return viewItem;
453     }
454 }
Popular Tags