View Javadoc

1   package com.explosion.expf;
2   
3   /*
4    * =============================================================================
5    * 
6    * Copyright 2004 Stephen Cowx
7    * 
8    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
9    * use this file except in compliance with the License. You may obtain a copy of
10   * the License at
11   * 
12   * http://www.apache.org/licenses/LICENSE-2.0
13   * 
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17   * License for the specific language governing permissions and limitations under
18   * the License.
19   * 
20   * =============================================================================
21   */
22  
23  import java.awt.Color;
24  import java.awt.Component;
25  import java.awt.Dimension;
26  import java.awt.event.ActionEvent;
27  import java.awt.event.KeyEvent;
28  import java.util.ArrayList;
29  import java.util.HashMap;
30  import java.util.Iterator;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.Vector;
34  
35  import javax.swing.ImageIcon;
36  import javax.swing.JFrame;
37  import javax.swing.JInternalFrame;
38  import javax.swing.RepaintManager;
39  import javax.swing.table.DefaultTableModel;
40  import javax.swing.table.TableModel;
41  
42  import org.apache.log4j.LogManager;
43  import org.apache.log4j.Logger;
44  
45  import com.explosion.expf.help.HelpPane;
46  import com.explosion.expf.preferences.StandardConfigurationDialog;
47  import com.explosion.expf.preferences.SystemPreferences;
48  import com.explosion.expf.preferences.Utils.PreferenceResizeRecorder;
49  import com.explosion.utilities.GeneralUtils;
50  import com.explosion.utilities.PrintUtilities;
51  import com.explosion.utilities.dialog.AboutDialog;
52  import com.explosion.utilities.dialog.SplashScreen;
53  import com.explosion.utilities.exception.ExceptionManagerFactory;
54  
55  /***
56   * @author Stephen Cowx Date created:@07-Feb-2003
57   * 
58  * <p>
59   * Listeners in expf applications work as follows.
60   * 
61   * <p>
62   * There is this listener, there are listeners that listen to global events,
63   * listeners that listen to local events and listeners that listen to component
64   * events. All events that are managed by the ApplicationFramework will come
65   * through this listener. Here they will either be responded to or propagated
66   * 
67   * <p>
68   * The difference between local and global events is that local events are
69   * events that must be applied to the currently active window and global events
70   * are events that apply to all windows whether they are active or not.
71   * 
72   * <p>
73   * e.g. "File >> Open" and "File >> Close all" are global events whereas "File
74   * >>" Save is a local event.
75   * 
76   * <p>
77   * Listeners need to be registered as either local or global listeners. They
78   * also need to be able to provide a list of events that they listen for i.e
79   * they should implement the ExpListener interface.
80   * 
81   * <P>
82   * For every event that occurs, the following logic is followed
83   * 
84   * 1) If events of this type are handled by this listener then it is handled
85   * here and not passed on. <br>
86   * 2) If it isn't handled by this listener then: <br>
87   * 3) A local listener is sought for the currently active window (by object
88   * reference) <br>
89   * 4) If there is one and it listens for events of this type, then the event is
90   * sent to this listener and not passed any furthur <br>
91   * 5) If there isn't one (or there is and it doesn't listen for event of this
92   * type) then the event is sent to each global listener that listenes for events
93   * of this type <br>
94   */
95  
96  public class ExpCompoundListener extends ExpListener
97  {
98  
99      private static Logger log = LogManager.getLogger(ExpCompoundListener.class);
100     private StandardConfigurationDialog confDialog;
101     private SplashScreen splashScreen;
102     private boolean splashed = false;
103     private List eventQueue = new ArrayList();
104 
105     private Map actionsHandledByThisListener;
106     private int[] keyCodesHandledByThisListener;
107 
108     private Map globalActionListeners = new HashMap();
109     private Map localActionListeners = new HashMap();
110     private Map componentActionListeners = new HashMap();
111 
112     private HelpPane helpPane = null;
113     private JFrame helpFrame = null;
114     private JInternalFrame helpInternalFrame = null;
115     private boolean busy = false;
116 
117     public ExpCompoundListener()
118     {
119         actionsHandledByThisListener = new HashMap();
120         actionsHandledByThisListener.put(ExpConstants.MENU_PROPERTIES, ExpConstants.MENU_PROPERTIES);
121         actionsHandledByThisListener.put(ExpConstants.MENU_EXIT, ExpConstants.MENU_EXIT);
122 
123         actionsHandledByThisListener.put(ExpConstants.MENU_ABOUT, ExpConstants.MENU_ABOUT);
124         actionsHandledByThisListener.put(ExpConstants.MENU_HELP_CONTENTS, ExpConstants.MENU_HELP_CONTENTS);
125         actionsHandledByThisListener.put(ExpConstants.MENU_PRINT, ExpConstants.MENU_PRINT);
126         for (Iterator it = ExpConstants.looksList.iterator(); it.hasNext();)
127         {
128             String command = (String) it.next();
129             actionsHandledByThisListener.put(command, command);
130         }
131     }
132 
133     /***
134      * This method contains the logic for processing method calls in a queue
135      * 
136      * @param call
137      */
138     private synchronized void queueMethodCall(QueuedMethodCall call)
139     {
140         if (busy)
141         {
142             log.debug("enqueueing" + call.hashCode() + " - " + call.getTypeDescription());
143             eventQueue.add(call);
144             return;
145         } else
146         {
147             busy = true;
148             log.debug("executing" + call.hashCode() + " - " + call.getTypeDescription());
149             try
150             {
151                 call.execute();
152             } catch (Exception e)
153             {
154                 //Report and swallow, we don't want the next event in the queue
155                 // to be affected
156                 ExceptionManagerFactory.getExceptionManager().manageException(e, "Excepion caught while responding to event.");
157             }
158 
159             while (true)
160             {
161                 if (eventQueue.size() > 0)
162                 {
163                     QueuedMethodCall nextCall = (QueuedMethodCall) eventQueue.get(0);
164                     log.debug("dequeued and executing" + nextCall.hashCode() + " - " + nextCall.getTypeDescription());
165                     try
166                     {
167                         nextCall.execute();
168                     } catch (Exception e)
169                     {
170                         //Report and swallow, we don't want the next event in
171                         // the queue to be affected
172                         ExceptionManagerFactory.getExceptionManager().manageException(e, "Excepion caught while responding to event.");
173                     } finally
174                     {
175                         eventQueue.remove(0);
176                     }
177                 } else
178                 {
179                     break;
180                 }
181             }
182 
183             busy = false;
184         }
185     }
186 
187     /***
188      * Queue's this method call for inbvoking later
189      * 
190      * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
191      * @param e
192      */
193     public synchronized void actionPerformed(ActionEvent e)
194     {
195         log.debug("actionPerformed");
196         List args = new ArrayList();
197         args.add(e);
198         queueMethodCall(new QueuedMethodCall(this, QueuedMethodCall.EVENT, args));
199     }
200 
201     /***
202      * This method adds a global ExpAction Listener to the compound listener An
203      * application can have more than one listener per reference. When events
204      * are handled, the CompundListener will iterate through all of the
205      * listeners for that reference in the order in which they were added.
206      * 
207      * @param listener
208      */
209     public void addGlobalActionListener(ExpActionListener listener, Object reference)
210     {
211         log.debug("addGlobalActionListener");
212         List args = new ArrayList();
213         args.add(listener);
214         args.add(reference);
215         queueMethodCall(new QueuedMethodCall(this, QueuedMethodCall.ADD_GLOBALLISTENER, args));
216     }
217 
218     /***
219      * This method removes all of the global action listener from the compound
220      * listener for the given reference
221      * 
222      * @param listener
223      */
224     public void removeGlobalActionListenersForReference(Object reference)
225     {
226         log.debug("removeGlobalActionListenersForReference");
227         List args = new ArrayList();
228         args.add(reference);
229         queueMethodCall(new QueuedMethodCall(this, QueuedMethodCall.REMOVE_GLOBALLISTENER, args));
230     }
231 
232     /***
233      * This method adds a local ExpAction Listener to the compound listener
234      * 
235      * @param listener
236      */
237     public void addLocalActionListener(ExpActionListener listener, Object reference)
238     {
239         log.debug("addLocalActionListener");
240         List args = new ArrayList();
241         args.add(listener);
242         args.add(reference);
243         queueMethodCall(new QueuedMethodCall(this, QueuedMethodCall.ADD_LOCALLISTENER, args));
244     }
245 
246     /***
247      * This method removes the specified local action listener from the compound
248      * listener
249      * 
250      * @param listener
251      */
252     public void removeLocalActionListenerForReference(ExpActionListener listener, Object reference)
253     {
254         log.debug("removeLocalActionListenerForReference");
255         List args = new ArrayList();
256         args.add(listener);
257         args.add(reference);
258         queueMethodCall(new QueuedMethodCall(this, QueuedMethodCall.REMOVE_LOCALLISTENER, args));
259     }
260 
261     /***
262      * This method adds a component ExpAction Listener to the compound listener
263      * 
264      * @param listener
265      */
266     public void addComponentActionListener(ExpActionListener listener, Object localReference, Object componentReference)
267     {
268         log.debug("addComponentActionListener");
269         List args = new ArrayList();
270         args.add(listener);
271         args.add(localReference);
272         args.add(componentReference);
273         queueMethodCall(new QueuedMethodCall(this, QueuedMethodCall.ADD_COMPONENT_LISTENER, args));
274     }
275 
276     /***
277      * This method removes the specified component action listener from the
278      * compound listener
279      * 
280      * @param listener
281      */
282     public void removeComponentActionListenerForReference(ExpActionListener listener, Object localReference)
283     {
284         log.debug("removeComponentActionListenerForReference");
285         List args = new ArrayList();
286         args.add(listener);
287         args.add(localReference);
288         queueMethodCall(new QueuedMethodCall(this, QueuedMethodCall.REMOVE_COMPONENT_LISTENER, args));
289     }
290 
291     /***
292      * Clean sup all references to any objects registered with this reference
293      */
294     public void cleanUpForReference(Object reference)
295     {
296         log.debug("cleanUpForReference");
297         List args = new ArrayList();
298         args.add(reference);
299         queueMethodCall(new QueuedMethodCall(this, QueuedMethodCall.CLEAN_UP, args));
300     }
301 
302     /***
303      * This method contains the logic for executing method calls in the order in
304      * which they were received.
305      * 
306      * @param e
307      */
308     protected void q_execute(ActionEvent e)
309     {
310         String command = e.getActionCommand();
311         log.debug("q_execute " + command);
312 
313         /*
314          * First check to see if this action is actually handled by this
315          * listener, if it isnt then delegate
316          */
317         if (actionsHandledByThisListener.get(command) == null)
318         {
319             log.debug("Event not handled by CompoundListener, delegating to locals and globals.");
320 
321             /*
322              * Check to see if there are any local listeners interested in this
323              * event
324              */
325             Object reference = Application.getLocalReference();
326             boolean handled = false;
327             if (reference != null)
328             {
329                 if (localActionListeners != null)
330                 {
331                     log.debug("Local reference found: " + reference);
332                     ArrayList locals = (ArrayList) localActionListeners.get(reference);
333                     if (locals != null)
334                     {
335                         log.debug(locals.size() + " local listeners found for the reference, event being sent to all of them.");
336                         for (int i = locals.size() - 1; i >= 0; i--)
337                         {
338                             ExpActionListener localActionListener = (ExpActionListener) locals.get(i);
339                             if (localActionListener != null && localActionListener.getListensFor().get(command) != null)
340                             {
341                                 log.debug("Local listener " + localActionListener + " is listening for this event and is being sent it.");
342                                 localActionListener.actionPerformed(e);
343                                 handled = true;
344                             } else
345                             {
346                                 if (localActionListener == null)
347                                     log.debug("Local listener " + localActionListener + " not listening for this event and is being skipped.");
348                                 else
349                                     log.debug("Local listener is null and is being skipped.");
350                             }
351                         }
352                     } else
353                     {
354                         log.debug("No local listeners found for the reference.");
355                     }
356                 }
357 
358                 if (componentActionListeners != null)
359                 {
360                     log.debug("There are component listeners, checking for active component.");
361                     Object activeComponent = Application.getActiveComponent();
362                     if (activeComponent != null)
363                     {
364                         log.debug("Active component found: " + activeComponent);
365                         log.debug("Checking for listeners for this component.");
366                         Map localComponents = (Map) componentActionListeners.get(reference);
367                         if (localComponents != null)
368                         {
369                             ArrayList listenersForActiveCompenent = (ArrayList) localComponents.get(activeComponent);
370                             if (listenersForActiveCompenent != null)
371                             {
372                                 log.debug(listenersForActiveCompenent.size() + " local listeners found for active component");
373                                 Iterator it = listenersForActiveCompenent.iterator();
374                                 while (it.hasNext())
375                                 {
376                                     ExpActionListener listenerForActiveComponent = (ExpActionListener) it.next();
377                                     if (listenerForActiveComponent.getListensFor().get(command) != null)
378                                     {
379                                         log.debug("Component listener " + listenerForActiveComponent + " is listening for this event and is being sent it.");
380                                         listenerForActiveComponent.actionPerformed(e);
381                                         handled = true;
382                                     } else
383                                     {
384                                         log.debug("Component listener " + listenerForActiveComponent + " not listening for this event and is being skipped.");
385                                     }
386                                 }
387                             }
388                         } else
389                         {
390                             log.debug("No listeners found this component.");
391                         }
392                     } else
393                     {
394                         log.debug("No active component found.");
395                     }
396                 }
397 
398                 if (((ExpFrame) Application.getApplicationFrame()) != null)
399                     ((ExpFrame) Application.getApplicationFrame()).checkEnabled();
400 
401                 if (handled)
402                 {
403                     log.debug("Returning from CompoundListener actionPerformed().");
404                     return;
405                 }
406             } else
407             {
408                 log.debug("Application currently has has no local references.");
409             }
410             /*
411              * If not, check to see if there are any global listeners interested
412              * in this event
413              */
414             if (globalActionListeners != null)
415             {
416                 log.debug(globalActionListeners.size() + " global references found.");
417                 Iterator it = globalActionListeners.keySet().iterator();
418                 while (it.hasNext())
419                 {
420                     Object key = it.next();
421                     ArrayList globals = (ArrayList) globalActionListeners.get(key);
422                     if (globals != null)
423                     {
424                         log.debug("Reference " + key + " has " + globals.size() + " global listeners.");
425                         for (int i = 0; i < globals.size(); i++)
426                         {
427                             ExpActionListener actionListener = (ExpActionListener) globals.get(i);
428                             if (actionListener.getListensFor() != null && actionListener.getListensFor().get(command) != null)
429                             {
430                                 log.debug("Global listener " + actionListener + " is listening for this event and is being sent it.");
431                                 actionListener.actionPerformed(e);
432                                 ((ExpFrame) Application.getApplicationFrame()).checkEnabled();
433                             } else
434                             {
435                                 if (actionListener != null)
436                                     log.debug("Global listener " + actionListener + " not listening for this event and is being skipped.");
437                                 else
438                                     log.debug("Global listener is null and is being skipped.");
439                             }
440                         }
441                     } else
442                     {
443                         log.debug("Reference " + key + " has no global listeners.");
444                     }
445 
446                 }
447                 log.debug("Returning from CompoundListener actionPerformed().");
448                 return;
449             }
450 
451         }
452 
453         /* If this actionis handled by this listener then handle it */
454         if (command.equals(ExpConstants.MENU_PROPERTIES))
455         {
456             confDialog = new StandardConfigurationDialog(Application.getApplicationFrame(), "Options");
457             confDialog.loadPreferences(SystemPreferences.getPreferences());
458             confDialog.setVisible(true);
459             
460         } else if (command.equals(ExpConstants.MENU_EXIT))
461         {
462             Application.getInstance().exit();
463         } 
464         else if (ExpConstants.looksMap.get(command) != null)
465         {
466             //This is the response for look and feel changes
467             try
468             {
469                 SystemPreferences.getPreference(ExpConstants.LAF).setValue(((ExpLookAndFeel)ExpConstants.looksMap.get(command)).getClassName()) ;     
470                 Application.getInstance().updateLookAndFeel();
471             } catch (Exception ex)
472             {
473                 com.explosion.utilities.exception.ExceptionManagerFactory.getExceptionManager().manageException(ex, "Exception caught while updating look and feel.");
474             }
475         } 
476         else if (command.equals(ExpConstants.MENU_HELP_CONTENTS))
477         {
478             try
479             {
480                 displayHelp();
481             } catch (Exception ex)
482             {
483                 ExceptionManagerFactory.getExceptionManager().manageException(ex, "Exception while trying to display help.");
484             }
485         } else if (command.equals(ExpConstants.MENU_ABOUT))
486         {
487             String applicationName = (String) SystemPreferences.getPreference(ExpConstants.EXPF_APP_NAME).getValue();
488             String applicationVersion = (String) SystemPreferences.getPreference(ExpConstants.EXPF_APP_VERSION).getValue();
489             String vendor = (String) SystemPreferences.getPreference(ExpConstants.EXPF_APP_VENDOR).getValue();
490             String author = (String) SystemPreferences.getPreference(ExpConstants.EXPF_APP_AUTHOR).getValue();
491             String year = (String) SystemPreferences.getPreference(ExpConstants.EXPF_APP_COPYRIGHT_YEAR).getValue();
492             String vendorUrl = (String) SystemPreferences.getPreference(ExpConstants.EXPF_APP_VENDOR_URL).getValue();
493 
494             Map map = new HashMap();
495             map.put("Modules", getModulesModel());
496             AboutDialog dialog = new AboutDialog(Application.getAboutImage(), applicationName, applicationVersion, vendor, author, year, vendorUrl, Color.white,map, Application.getApplicationFrame());
497             GeneralUtils.centreWindowInParent(dialog);
498             dialog.setVisible(true);
499         } else if (command.equals(ExpConstants.MENU_PRINT))
500         {
501             RepaintManager currentManager = RepaintManager.currentManager(Application.getApplicationFrame());
502             currentManager.setDoubleBufferingEnabled(false);
503             PrintUtilities.printComponent((Component) Application.getActiveComponent());
504             currentManager.setDoubleBufferingEnabled(true);
505         }
506 
507         if (((ExpFrame) Application.getApplicationFrame()) != null)
508             ((ExpFrame) Application.getApplicationFrame()).checkEnabled();
509     }
510     
511     /***
512      * Returns a tableModel containing information about the modules included in this 
513      * application.
514      * @return
515      */
516     private TableModel getModulesModel()
517     {
518         Vector vector = Application.getModules();
519         Vector columns = new Vector();
520         columns.add("Name");
521         columns.add("Description");
522         columns.add("Version");
523         
524         Vector rows = new Vector();
525         
526         for (int i=0;i<vector.size();i++)
527         { 
528             Vector row = new Vector();
529             ExpModuleManager manager = (ExpModuleManager) vector.get(i);
530             row.add(manager.getName());
531             row.add(manager.getDescription());
532             row.add(manager.getVersion());
533             rows.add(row);
534         }
535         return new DefaultTableModel(rows,columns);
536     }
537 
538     /***
539      * This method adds a global ExpAction Listener to the compound listener An
540      * application can have more than one listener per reference. When events
541      * are handled, the CompundListener will iterate through all of the
542      * listeners for that reference in the order in which they were added.
543      * 
544      * @param listener
545      */
546     protected void q_addGlobalActionListener(ExpActionListener listener, Object reference)
547     {
548         log.debug("q_addGlobalActionListener");
549         if (listener == null)
550             return;
551 
552         if (globalActionListeners == null)
553         {
554             globalActionListeners = new HashMap();
555             ArrayList listenersForReference = new ArrayList();
556             listenersForReference.add(listener);
557             globalActionListeners.put(reference, listenersForReference);
558         } else
559         {
560             ArrayList listenersForReference = (ArrayList) globalActionListeners.get(reference);
561             if (listenersForReference != null)
562             {
563                 if (!listenersForReference.contains(listener))
564                     listenersForReference.add(listener);
565             } else
566             {
567                 listenersForReference = new ArrayList();
568                 listenersForReference.add(listener);
569                 globalActionListeners.put(reference, listenersForReference);
570             }
571         }
572     }
573 
574     /***
575      * This method removes all of the global action listener from the compound
576      * listener for the given reference
577      * 
578      * @param listener
579      */
580     protected void q_removeGlobalActionListenersForReference(Object reference)
581     {
582         log.debug("q_removeGlobalActionListenersForReference");
583         if (reference == null)
584             return;
585 
586         if (globalActionListeners == null)
587             return;
588 
589         globalActionListeners.remove(reference);
590     }
591 
592     /***
593      * This method adds a local ExpAction Listener to the compound listener
594      * 
595      * @param listener
596      */
597     protected void q_addLocalActionListener(ExpActionListener listener, Object reference)
598     {
599         log.debug("q_addLocalActionListener");
600         if (listener == null)
601             return;
602 
603         if (localActionListeners == null)
604         {
605             localActionListeners = new HashMap();
606             ArrayList listenersForReference = new ArrayList();
607             listenersForReference.add(listener);
608             localActionListeners.put(reference, listenersForReference);
609         } else
610         {
611             ArrayList listenersForReference = (ArrayList) localActionListeners.get(reference);
612             if (listenersForReference != null)
613             {
614                 if (!listenersForReference.contains(listener))
615                     listenersForReference.add(listener);
616             } else
617             {
618                 listenersForReference = new ArrayList();
619                 listenersForReference.add(listener);
620                 localActionListeners.put(reference, listenersForReference);
621             }
622         }
623     }
624 
625     /***
626      * This method removes the specified local action listener from the compound
627      * listener
628      * 
629      * @param listener
630      */
631     protected void q_removeLocalActionListenerForReference(ExpActionListener listener, Object reference)
632     {
633         log.debug("q_removeLocalActionListenerForReference");
634         if (localActionListeners == null)
635             return;
636 
637         localActionListeners.remove(reference);
638     }
639 
640     /***
641      * This method adds a component ExpAction Listener to the compound listener
642      * 
643      * @param listener
644      */
645     protected void q_addComponentActionListener(ExpActionListener listener, Object localReference, Object componentReference)
646     {
647         log.debug("q_addComponentActionListener");
648         if (listener == null)
649             return;
650 
651         log.debug("Adding component listener " + listener + " for component  " + componentReference + " for local reference " + localReference);
652         if (componentActionListeners == null)
653         {
654             log.debug("Component action listeners does not exist.");
655             ArrayList listenersForComponent = new ArrayList();
656             listenersForComponent.add(listener);
657 
658             HashMap listenersForReference = new HashMap();
659             listenersForReference.put(componentReference, listenersForComponent);
660 
661             componentActionListeners = new HashMap();
662             componentActionListeners.put(localReference, listenersForReference);
663         } else
664         {
665             log.debug("Component action listeners exists.");
666             HashMap listenersForReference = (HashMap) componentActionListeners.get(localReference);
667             if (listenersForReference != null)
668             {
669                 log.debug("There are Listeners for this reference");
670                 if (listenersForReference.containsKey(componentReference))
671                 {
672                     log.debug("There are listeners for this component");
673                     ArrayList listenersForComponent = (ArrayList) listenersForReference.get(componentReference);
674                     listenersForComponent.add(listener);
675                 } else
676                 {
677                     log.debug("There are no listeners previous for this component.");
678                     ArrayList listenersForComponent = new ArrayList();
679                     listenersForComponent.add(listener);
680                     listenersForReference.put(componentReference, listenersForComponent);
681                 }
682             } else
683             {
684                 log.debug("There are no previous listeners for this reference");
685                 ArrayList listenersForComponent = new ArrayList();
686                 listenersForComponent.add(listener);
687 
688                 listenersForReference = new HashMap();
689                 listenersForReference.put(componentReference, listenersForComponent);
690 
691                 componentActionListeners.put(localReference, listenersForReference);
692             }
693         }
694     }
695 
696     /***
697      * This method removes the specified component action listener from the
698      * compound listener
699      * 
700      * @param listener
701      */
702     protected void q_removeComponentActionListenerForReference(ExpActionListener listener, Object localReference)
703     {
704         log.debug("q_removeComponentActionListenerForReference");
705         if (componentActionListeners == null)
706             return;
707 
708         componentActionListeners.remove(localReference);
709     }
710 
711     /***
712      * Clean sup all references to any objects registered with this reference
713      */
714     protected void q_cleanUpForReference(Object reference)
715     {
716         log.debug("q_cleanUpForReference started");
717         if (localActionListeners != null)
718             localActionListeners.remove(reference);
719 
720         if (globalActionListeners != null)
721             globalActionListeners.remove(reference);
722 
723         if (componentActionListeners != null)
724             componentActionListeners.remove(reference);
725         
726         log.debug("q_cleanUpForReference finished");
727     }
728 
729     /***
730      * logic for displaying thehelp screen in its correct format
731      */
732     private void displayHelp() throws Exception
733     {
734         int heightOfIt = ((Integer) SystemPreferences.getPreference(ExpConstants.HELP_HEIGHT).getValue()).intValue();
735         int widthOfIt = ((Integer) SystemPreferences.getPreference(ExpConstants.HELP_WIDTH).getValue()).intValue();
736 
737         if (helpPane == null)
738             helpPane = new HelpPane((String) SystemPreferences.getPreference(ExpConstants.HELP_STARTUP_ID).getValue());
739 
740         boolean helpEmbedded = ((Boolean) SystemPreferences.getPreference(ExpConstants.HELP_EMBEDDED).getValue()).booleanValue();
741         if (helpEmbedded)
742         {
743 
744             helpInternalFrame = ((ExpFrame) Application.getApplicationFrame()).getFrameWithComponent(helpPane, ExpFrame.PALETTE_LAYER.intValue());
745             if (helpInternalFrame != null)
746             {
747                 if (helpInternalFrame.isVisible())
748                     return;
749                 else
750                 {
751                     Application.getInstance().updateLookAndFeel(helpInternalFrame);
752                     helpInternalFrame.setVisible(true);
753                     return;
754                 }
755             }
756 
757             if (helpFrame != null && helpFrame.isVisible())
758                 helpFrame.setVisible(false);
759 
760             ExpInternalFrame frame = ((ExpFrame) Application.getApplicationFrame()).createPaletteFrame(helpPane, new Dimension(widthOfIt, heightOfIt), "Help",false);
761             frame.addSizePersistence(SystemPreferences.getPreference(ExpConstants.HELP_HEIGHT), SystemPreferences.getPreference(ExpConstants.HELP_WIDTH));
762             frame.centreInParent();
763         } else
764         {
765             if (helpFrame == null)
766             {
767                 helpFrame = new JFrame("Help");
768                 ImageIcon icon = ((ExpFrame) Application.getApplicationFrame()).getFrameIcon();
769                 if (icon != null)
770                     helpFrame.setIconImage(icon.getImage());
771 
772                 helpFrame.setContentPane(helpPane);
773                 helpFrame.setSize(widthOfIt, heightOfIt);
774 
775                 GeneralUtils.centreWindowInParent(helpFrame, Application.getApplicationFrame());
776                 helpFrame.addComponentListener(new PreferenceResizeRecorder(SystemPreferences.getPreference(ExpConstants.HELP_HEIGHT), SystemPreferences.getPreference(ExpConstants.HELP_WIDTH),
777                         helpFrame));
778 
779             } else if (helpFrame.isVisible())
780                 return;
781 
782             if (helpInternalFrame != null && helpInternalFrame.isVisible())
783                 helpInternalFrame.setVisible(false);
784 
785             helpFrame.setContentPane(helpPane);
786             Application.getInstance().updateLookAndFeel(helpFrame);
787             helpFrame.setVisible(true);
788         }
789     }
790 
791     /***
792      * This method sets the look and feel of the help frame and it's children
793      * This is done because it doesn't happen automatically
794      */
795     protected void updateLookAndFeelOfHelp() throws Exception
796     {
797         boolean helpEmbedded = ((Boolean) SystemPreferences.getPreference(ExpConstants.HELP_EMBEDDED).getValue()).booleanValue();
798         boolean showing = false;
799         
800         /* Help is currently embedded and we don;t want it to be */
801         if (helpInternalFrame != null && !helpEmbedded)
802         {
803             /* Check if it is already showing */
804             if (helpInternalFrame.isVisible())
805                  showing = true;
806             
807             /* Close the frame */
808             ((ExpFrame) Application.getApplicationFrame()).closeFrameWithComponent(helpPane,ExpFrame.PALETTE_LAYER);
809         }
810         
811         if (helpFrame != null)
812         {
813             if (helpFrame.isVisible())
814                 showing = true;
815             
816             helpFrame.dispose();
817             helpPane = null;
818         }
819         
820         
821         if (showing)
822             displayHelp();             
823 
824     }
825 
826     /***
827      * Responds to for F1 key code currently. It pops up a help window assuming
828      * it recieves the event.
829      */
830     public void keyPressed(KeyEvent e)
831     {
832     }
833 
834     /***
835      * Does nothing currently
836      */
837     public void keyReleased(KeyEvent e)
838     {}
839 
840     /***
841      * Does nothing currently
842      */
843     public void keyTyped(KeyEvent e)
844     {}
845 
846 }
847 
848 /***
849  * An object representing a method call. The method call is delayed until the
850  * correct time and then executed. This is not done with reflection to keep it
851  * simple
852  * 
853  * @author Stephen Created on Apr 12, 2004
854  */
855 
856 class QueuedMethodCall
857 {
858 
859     private static Logger log = LogManager.getLogger(QueuedMethodCall.class);
860     public static final int EVENT = 0;
861     public static final int ADD_LOCALLISTENER = 1;
862     public static final int ADD_GLOBALLISTENER = 2;
863     public static final int ADD_COMPONENT_LISTENER = 3;
864 
865     public static final int REMOVE_LOCALLISTENER = 4;
866     public static final int REMOVE_GLOBALLISTENER = 5;
867     public static final int REMOVE_COMPONENT_LISTENER = 6;
868 
869     public static final int CLEAN_UP = 7;
870 
871     public List arguments;
872     private int type = 0;
873     private ExpCompoundListener listener;
874 
875     public QueuedMethodCall(ExpCompoundListener listener, int type, List arguments)
876     {
877         this.type = type;
878         this.arguments = arguments;
879         this.listener = listener;
880     }
881 
882     public void execute()
883     {
884         switch (type)
885         {
886         case (EVENT):
887             listener.q_execute((ActionEvent) arguments.get(0));
888             break;
889         case (ADD_LOCALLISTENER):
890             listener.q_addLocalActionListener((ExpActionListener) arguments.get(0), arguments.get(1));
891             break;
892         case (ADD_GLOBALLISTENER):
893             listener.q_addGlobalActionListener((ExpActionListener) arguments.get(0), arguments.get(1));
894             break;
895         case (ADD_COMPONENT_LISTENER):
896             listener.q_addComponentActionListener((ExpActionListener) arguments.get(0), arguments.get(1), arguments.get(2));
897             break;
898         case (REMOVE_LOCALLISTENER):
899             listener.q_removeLocalActionListenerForReference((ExpActionListener) arguments.get(0), arguments.get(1));
900             break;
901         case (REMOVE_GLOBALLISTENER):
902             listener.q_removeGlobalActionListenersForReference(arguments.get(0));
903             break;
904         case (REMOVE_COMPONENT_LISTENER):
905             listener.q_removeLocalActionListenerForReference((ExpActionListener) arguments.get(0), arguments.get(1));
906             break;
907         case (CLEAN_UP):
908             listener.q_cleanUpForReference(arguments.get(0));
909             break;
910         }
911     }
912 
913     /***
914      * @return Returns the arguments.
915      */
916     public List getArguments()
917     {
918         return arguments;
919     }
920 
921     /***
922      * @param arguments The arguments to set.
923      */
924     public void setArguments(List arguments)
925     {
926         this.arguments = arguments;
927     }
928 
929     /***
930      * @return Returns the type.
931      */
932     public int getType()
933     {
934         return type;
935     }
936 
937     /***
938      * @return Returns the type as a descriptive string
939      */
940     public String getTypeDescription()
941     {
942         switch (type)
943         {
944         case (EVENT):
945             return "EVENT-" + ((ActionEvent) arguments.get(0)).getActionCommand();
946         case (ADD_LOCALLISTENER):
947             return "ADD_LOCALLISTENER";
948         case (ADD_GLOBALLISTENER):
949             return "ADD_GLOBALLISTENER";
950         case (ADD_COMPONENT_LISTENER):
951             return "ADD_COMPONENT_LISTENER";
952         case (REMOVE_LOCALLISTENER):
953             return "REMOVE_LOCALLISTENER";
954         case (REMOVE_GLOBALLISTENER):
955             return "REMOVE_GLOBALLISTENER";
956         case (REMOVE_COMPONENT_LISTENER):
957             return "REMOVE_COMPONENT_LISTENER";
958         case (CLEAN_UP):
959             return "CLEAN_UP";
960         default:
961             return "NO DESCRIPTION FOR THIS EVENT FOUND";
962         }
963     }
964 
965     /***
966      * @param type The type to set.
967      */
968     public void setType(int type)
969     {
970         this.type = type;
971     }
972 }