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 NonCompoundExpListener extends ExpListener
97  {
98  
99      private static Logger log = LogManager.getLogger(NonCompoundExpListener.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     /***
118      * Constructs this listener
119      *
120      */
121     public NonCompoundExpListener()
122     {
123         actionsHandledByThisListener = new HashMap();
124         actionsHandledByThisListener.put(ExpConstants.MENU_PROPERTIES, ExpConstants.MENU_PROPERTIES);
125         actionsHandledByThisListener.put(ExpConstants.MENU_EXIT, ExpConstants.MENU_EXIT);
126 
127         actionsHandledByThisListener.put(ExpConstants.MENU_ABOUT, ExpConstants.MENU_ABOUT);
128         actionsHandledByThisListener.put(ExpConstants.MENU_HELP_CONTENTS, ExpConstants.MENU_HELP_CONTENTS);
129         actionsHandledByThisListener.put(ExpConstants.MENU_PRINT, ExpConstants.MENU_PRINT);
130         for (Iterator it = ExpConstants.looksList.iterator(); it.hasNext();)
131         {
132             String command = (String) it.next();
133             actionsHandledByThisListener.put(command, command);
134         }
135     }
136 
137     /***
138      * Action performed
139      * 
140      * @param e
141      */
142     public synchronized void actionPerformed(ActionEvent e)
143     {
144         String command = e.getActionCommand();
145         log.debug("q_execute " + command);
146 
147         /*
148          * First check to see if this action is actually handled by this
149          * listener, if it isnt then delegate
150          */
151         if (actionsHandledByThisListener.get(command) == null)
152         {
153             log.debug("Event not handled by CompoundListener, delegating to locals and globals.");
154 
155             /*
156              * Check to see if there are any local listeners interested in this
157              * event
158              */
159             Object reference = Application.getLocalReference();
160             boolean handled = false;
161             if (reference != null)
162             {
163                 if (localActionListeners != null)
164                 {
165                     log.debug("Local reference found: " + reference);
166                     ArrayList locals = (ArrayList) localActionListeners.get(reference);
167                     if (locals != null)
168                     {
169                         log.debug(locals.size() + " local listeners found for the reference, event being sent to all of them.");
170                         for (int i = locals.size() - 1; i >= 0; i--)
171                         {
172                             ExpActionListener localActionListener = (ExpActionListener) locals.get(i);
173                             if (localActionListener != null && localActionListener.getListensFor().get(command) != null)
174                             {
175                                 log.debug("Local listener " + localActionListener + " is listening for this event and is being sent it.");
176                                 localActionListener.actionPerformed(e);
177                                 handled = true;
178                             } else
179                             {
180                                 if (localActionListener == null)
181                                     log.debug("Local listener " + localActionListener + " not listening for this event and is being skipped.");
182                                 else
183                                     log.debug("Local listener is null and is being skipped.");
184                             }
185                         }
186                     } else
187                     {
188                         log.debug("No local listeners found for the reference.");
189                     }
190                 }
191 
192                 if (componentActionListeners != null)
193                 {
194                     log.debug("There are component listeners, checking for active component.");
195                     Object activeComponent = Application.getActiveComponent();
196                     if (activeComponent != null)
197                     {
198                         log.debug("Active component found: " + activeComponent);
199                         log.debug("Checking for listeners for this component.");
200                         Map localComponents = (Map) componentActionListeners.get(reference);
201                         if (localComponents != null)
202                         {
203                             ArrayList listenersForActiveCompenent = (ArrayList) localComponents.get(activeComponent);
204                             if (listenersForActiveCompenent != null)
205                             {
206                                 log.debug(listenersForActiveCompenent.size() + " local listeners found for active component");
207                                 Iterator it = listenersForActiveCompenent.iterator();
208                                 while (it.hasNext())
209                                 {
210                                     ExpActionListener listenerForActiveComponent = (ExpActionListener) it.next();
211                                     if (listenerForActiveComponent.getListensFor().get(command) != null)
212                                     {
213                                         log.debug("Component listener " + listenerForActiveComponent + " is listening for this event and is being sent it.");
214                                         listenerForActiveComponent.actionPerformed(e);
215                                         handled = true;
216                                     } else
217                                     {
218                                         log.debug("Component listener " + listenerForActiveComponent + " not listening for this event and is being skipped.");
219                                     }
220                                 }
221                             }
222                         } else
223                         {
224                             log.debug("No listeners found this component.");
225                         }
226                     } else
227                     {
228                         log.debug("No active component found.");
229                     }
230                 }
231 
232                 if (((ExpFrame) Application.getApplicationFrame()) != null)
233                     ((ExpFrame) Application.getApplicationFrame()).checkEnabled();
234 
235                 if (handled)
236                 {
237                     log.debug("Returning from CompoundListener actionPerformed().");
238                     return;
239                 }
240             } else
241             {
242                 log.debug("Application currently has has no local references.");
243             }
244             /*
245              * If not, check to see if there are any global listeners interested
246              * in this event
247              */
248             if (globalActionListeners != null)
249             {
250                 log.debug(globalActionListeners.size() + " global references found.");
251                 Iterator it = globalActionListeners.keySet().iterator();
252                 while (it.hasNext())
253                 {
254                     Object key = it.next();
255                     ArrayList globals = (ArrayList) globalActionListeners.get(key);
256                     if (globals != null)
257                     {
258                         log.debug("Reference " + key + " has " + globals.size() + " global listeners.");
259                         for (int i = 0; i < globals.size(); i++)
260                         {
261                             ExpActionListener actionListener = (ExpActionListener) globals.get(i);
262                             if (actionListener.getListensFor() != null && actionListener.getListensFor().get(command) != null)
263                             {
264                                 log.debug("Global listener " + actionListener + " is listening for this event and is being sent it.");
265                                 actionListener.actionPerformed(e);
266                                 ((ExpFrame) Application.getApplicationFrame()).checkEnabled();
267                             } else
268                             {
269                                 if (actionListener != null)
270                                     log.debug("Global listener " + actionListener + " not listening for this event and is being skipped.");
271                                 else
272                                     log.debug("Global listener is null and is being skipped.");
273                             }
274                         }
275                     } else
276                     {
277                         log.debug("Reference " + key + " has no global listeners.");
278                     }
279 
280                 }
281                 log.debug("Returning from CompoundListener actionPerformed().");
282                 return;
283             }
284 
285         }
286 
287         /* If this actionis handled by this listener then handle it */
288         if (command.equals(ExpConstants.MENU_PROPERTIES))
289         {
290             confDialog = new StandardConfigurationDialog(Application.getApplicationFrame(), "Options");
291             confDialog.loadPreferences(SystemPreferences.getPreferences());
292             confDialog.setVisible(true);
293             
294         } else if (command.equals(ExpConstants.MENU_EXIT))
295         {
296             Application.getInstance().exit();
297         } 
298         else if (ExpConstants.looksMap.get(command) != null)
299         {
300             //This is the response for look and feel changes
301             try
302             {
303                 SystemPreferences.getPreference(ExpConstants.LAF).setValue(((ExpLookAndFeel)ExpConstants.looksMap.get(command)).getClassName()) ;     
304                 Application.getInstance().updateLookAndFeel();
305             } catch (Exception ex)
306             {
307                 com.explosion.utilities.exception.ExceptionManagerFactory.getExceptionManager().manageException(ex, "Exception caught while updating look and feel.");
308             }
309         } 
310         else if (command.equals(ExpConstants.MENU_HELP_CONTENTS))
311         {
312             try
313             {
314                 displayHelp();
315             } catch (Exception ex)
316             {
317                 ExceptionManagerFactory.getExceptionManager().manageException(ex, "Exception while trying to display help.");
318             }
319         } else if (command.equals(ExpConstants.MENU_ABOUT))
320         {
321             String applicationName = (String) SystemPreferences.getPreference(ExpConstants.EXPF_APP_NAME).getValue();
322             String applicationVersion = (String) SystemPreferences.getPreference(ExpConstants.EXPF_APP_VERSION).getValue();
323             String vendor = (String) SystemPreferences.getPreference(ExpConstants.EXPF_APP_VENDOR).getValue();
324             String author = (String) SystemPreferences.getPreference(ExpConstants.EXPF_APP_AUTHOR).getValue();
325             String year = (String) SystemPreferences.getPreference(ExpConstants.EXPF_APP_COPYRIGHT_YEAR).getValue();
326             String vendorUrl = (String) SystemPreferences.getPreference(ExpConstants.EXPF_APP_VENDOR_URL).getValue();
327 
328             Map map = new HashMap();
329             map.put("Modules", getModulesModel());
330             AboutDialog dialog = new AboutDialog(Application.getAboutImage(), applicationName, applicationVersion, vendor, author, year, vendorUrl, Color.white,map, Application.getApplicationFrame());
331             GeneralUtils.centreWindowInParent(dialog);
332             dialog.setVisible(true);
333         } else if (command.equals(ExpConstants.MENU_PRINT))
334         {
335             RepaintManager currentManager = RepaintManager.currentManager(Application.getApplicationFrame());
336             currentManager.setDoubleBufferingEnabled(false);
337             PrintUtilities.printComponent((Component) Application.getActiveComponent());
338             currentManager.setDoubleBufferingEnabled(true);
339         }
340 
341         if (((ExpFrame) Application.getApplicationFrame()) != null)
342             ((ExpFrame) Application.getApplicationFrame()).checkEnabled();
343     }
344     
345     /***
346      * Returns a tableModel containing information about the modules included in this 
347      * application.
348      * @return
349      */
350     private synchronized TableModel getModulesModel()
351     {
352         Vector vector = Application.getModules();
353         Vector columns = new Vector();
354         columns.add("Name");
355         columns.add("Description");
356         columns.add("Version");
357         
358         Vector rows = new Vector();
359         
360         for (int i=0;i<vector.size();i++)
361         { 
362             Vector row = new Vector();
363             ExpModuleManager manager = (ExpModuleManager) vector.get(i);
364             row.add(manager.getName());
365             row.add(manager.getDescription());
366             row.add(manager.getVersion());
367             rows.add(row);
368         }
369         return new DefaultTableModel(rows,columns);
370     }
371 
372     /***
373      * This method adds a global ExpAction Listener to the compound listener An
374      * application can have more than one listener per reference. When events
375      * are handled, the CompundListener will iterate through all of the
376      * listeners for that reference in the order in which they were added.
377      * 
378      * @param listener
379      */
380     public synchronized void addGlobalActionListener(ExpActionListener listener, Object reference)
381     {
382         log.debug("q_addGlobalActionListener");
383         if (listener == null)
384             return;
385 
386         if (globalActionListeners == null)
387         {
388             globalActionListeners = new HashMap();
389             ArrayList listenersForReference = new ArrayList();
390             listenersForReference.add(listener);
391             globalActionListeners.put(reference, listenersForReference);
392         } else
393         {
394             ArrayList listenersForReference = (ArrayList) globalActionListeners.get(reference);
395             if (listenersForReference != null)
396             {
397                 if (!listenersForReference.contains(listener))
398                     listenersForReference.add(listener);
399             } else
400             {
401                 listenersForReference = new ArrayList();
402                 listenersForReference.add(listener);
403                 globalActionListeners.put(reference, listenersForReference);
404             }
405         }
406     }
407 
408     /***
409      * This method removes all of the global action listener from the compound
410      * listener for the given reference
411      * 
412      * @param listener
413      */
414     public synchronized void removeGlobalActionListenersForReference(Object reference)
415     {
416         log.debug("q_removeGlobalActionListenersForReference");
417         if (reference == null)
418             return;
419 
420         if (globalActionListeners == null)
421             return;
422 
423         globalActionListeners.remove(reference);
424     }
425 
426     /***
427      * This method adds a local ExpAction Listener to the compound listener
428      * 
429      * @param listener
430      */
431     public synchronized void addLocalActionListener(ExpActionListener listener, Object reference)
432     {
433         log.debug("q_addLocalActionListener");
434         if (listener == null)
435             return;
436 
437         if (localActionListeners == null)
438         {
439             localActionListeners = new HashMap();
440             ArrayList listenersForReference = new ArrayList();
441             listenersForReference.add(listener);
442             localActionListeners.put(reference, listenersForReference);
443         } else
444         {
445             ArrayList listenersForReference = (ArrayList) localActionListeners.get(reference);
446             if (listenersForReference != null)
447             {
448                 if (!listenersForReference.contains(listener))
449                     listenersForReference.add(listener);
450             } else
451             {
452                 listenersForReference = new ArrayList();
453                 listenersForReference.add(listener);
454                 localActionListeners.put(reference, listenersForReference);
455             }
456         }
457     }
458 
459     /***
460      * This method removes the specified local action listener from the compound
461      * listener
462      * 
463      * @param listener
464      */
465     public synchronized void removeLocalActionListenerForReference(ExpActionListener listener, Object reference)
466     {
467         log.debug("q_removeLocalActionListenerForReference");
468         if (localActionListeners == null)
469             return;
470 
471         localActionListeners.remove(reference);
472     }
473 
474     /***
475      * This method adds a component ExpAction Listener to the compound listener
476      * 
477      * @param listener
478      */
479     public synchronized void addComponentActionListener(ExpActionListener listener, Object localReference, Object componentReference)
480     {
481         log.debug("q_addComponentActionListener");
482         if (listener == null)
483             return;
484 
485         log.debug("Adding component listener " + listener + " for component  " + componentReference + " for local reference " + localReference);
486         if (componentActionListeners == null)
487         {
488             log.debug("Component action listeners does not exist.");
489             ArrayList listenersForComponent = new ArrayList();
490             listenersForComponent.add(listener);
491 
492             HashMap listenersForReference = new HashMap();
493             listenersForReference.put(componentReference, listenersForComponent);
494 
495             componentActionListeners = new HashMap();
496             componentActionListeners.put(localReference, listenersForReference);
497         } else
498         {
499             log.debug("Component action listeners exists.");
500             HashMap listenersForReference = (HashMap) componentActionListeners.get(localReference);
501             if (listenersForReference != null)
502             {
503                 log.debug("There are Listeners for this reference");
504                 if (listenersForReference.containsKey(componentReference))
505                 {
506                     log.debug("There are listeners for this component");
507                     ArrayList listenersForComponent = (ArrayList) listenersForReference.get(componentReference);
508                     listenersForComponent.add(listener);
509                 } else
510                 {
511                     log.debug("There are no listeners previous for this component.");
512                     ArrayList listenersForComponent = new ArrayList();
513                     listenersForComponent.add(listener);
514                     listenersForReference.put(componentReference, listenersForComponent);
515                 }
516             } else
517             {
518                 log.debug("There are no previous listeners for this reference");
519                 ArrayList listenersForComponent = new ArrayList();
520                 listenersForComponent.add(listener);
521 
522                 listenersForReference = new HashMap();
523                 listenersForReference.put(componentReference, listenersForComponent);
524 
525                 componentActionListeners.put(localReference, listenersForReference);
526             }
527         }
528     }
529 
530     /***
531      * This method removes the specified component action listener from the
532      * compound listener
533      * 
534      * @param listener
535      */
536     public synchronized void removeComponentActionListenerForReference(ExpActionListener listener, Object localReference)
537     {
538         log.debug("q_removeComponentActionListenerForReference");
539         if (componentActionListeners == null)
540             return;
541 
542         componentActionListeners.remove(localReference);
543     }
544 
545     /***
546      * Clean sup all references to any objects registered with this reference
547      */
548     public synchronized void cleanUpForReference(Object reference)
549     {
550         log.debug("q_cleanUpForReference started");
551         if (localActionListeners != null)
552             localActionListeners.remove(reference);
553 
554         if (globalActionListeners != null)
555             globalActionListeners.remove(reference);
556 
557         if (componentActionListeners != null)
558             componentActionListeners.remove(reference);
559         
560         log.debug("q_cleanUpForReference finished");
561     }
562 
563     /***
564      * logic for displaying thehelp screen in its correct format
565      */
566     private void displayHelp() throws Exception
567     {
568         int heightOfIt = ((Integer) SystemPreferences.getPreference(ExpConstants.HELP_HEIGHT).getValue()).intValue();
569         int widthOfIt = ((Integer) SystemPreferences.getPreference(ExpConstants.HELP_WIDTH).getValue()).intValue();
570 
571         if (helpPane == null)
572             helpPane = new HelpPane((String) SystemPreferences.getPreference(ExpConstants.HELP_STARTUP_ID).getValue());
573 
574         boolean helpEmbedded = ((Boolean) SystemPreferences.getPreference(ExpConstants.HELP_EMBEDDED).getValue()).booleanValue();
575         if (helpEmbedded)
576         {
577 
578             helpInternalFrame = ((ExpFrame) Application.getApplicationFrame()).getFrameWithComponent(helpPane, ExpFrame.PALETTE_LAYER.intValue());
579             if (helpInternalFrame != null)
580             {
581                 if (helpInternalFrame.isVisible())
582                     return;
583                 else
584                 {
585                     Application.getInstance().updateLookAndFeel(helpInternalFrame);
586                     helpInternalFrame.setVisible(true);
587                     return;
588                 }
589             }
590 
591             if (helpFrame != null && helpFrame.isVisible())
592                 helpFrame.setVisible(false);
593 
594             ExpInternalFrame frame = ((ExpFrame) Application.getApplicationFrame()).createPaletteFrame(helpPane, new Dimension(widthOfIt, heightOfIt), "Help",false);
595             frame.addSizePersistence(SystemPreferences.getPreference(ExpConstants.HELP_HEIGHT), SystemPreferences.getPreference(ExpConstants.HELP_WIDTH));
596             frame.centreInParent();
597         } else
598         {
599             if (helpFrame == null)
600             {
601                 helpFrame = new JFrame("Help");
602                 ImageIcon icon = ((ExpFrame) Application.getApplicationFrame()).getFrameIcon();
603                 if (icon != null)
604                     helpFrame.setIconImage(icon.getImage());
605 
606                 helpFrame.setContentPane(helpPane);
607                 helpFrame.setSize(widthOfIt, heightOfIt);
608 
609                 GeneralUtils.centreWindowInParent(helpFrame, Application.getApplicationFrame());
610                 helpFrame.addComponentListener(new PreferenceResizeRecorder(SystemPreferences.getPreference(ExpConstants.HELP_HEIGHT), SystemPreferences.getPreference(ExpConstants.HELP_WIDTH),
611                         helpFrame));
612 
613             } else if (helpFrame.isVisible())
614                 return;
615 
616             if (helpInternalFrame != null && helpInternalFrame.isVisible())
617                 helpInternalFrame.setVisible(false);
618 
619             helpFrame.setContentPane(helpPane);
620             Application.getInstance().updateLookAndFeel(helpFrame);
621             helpFrame.setVisible(true);
622         }
623     }
624 
625     /***
626      * This method sets the look and feel of the help frame and it's children
627      * This is done because it doesn't happen automatically
628      */
629     protected void updateLookAndFeelOfHelp() throws Exception
630     {
631         boolean helpEmbedded = ((Boolean) SystemPreferences.getPreference(ExpConstants.HELP_EMBEDDED).getValue()).booleanValue();
632         boolean showing = false;
633         
634         /* Help is currently embedded and we don;t want it to be */
635         if (helpInternalFrame != null && !helpEmbedded)
636         {
637             /* Check if it is already showing */
638             if (helpInternalFrame.isVisible())
639                  showing = true;
640             
641             /* Close the frame */
642             ((ExpFrame) Application.getApplicationFrame()).closeFrameWithComponent(helpPane,ExpFrame.PALETTE_LAYER);
643         }
644         
645         if (helpFrame != null)
646         {
647             if (helpFrame.isVisible())
648                 showing = true;
649             
650             helpFrame.dispose();
651             helpPane = null;
652         }
653         
654         
655         if (showing)
656             displayHelp();             
657 
658     }
659 
660     /***
661      * Responds to for F1 key code currently. It pops up a help window assuming
662      * it recieves the event.
663      */
664     public synchronized void keyPressed(KeyEvent e)
665     {
666     }
667 
668     /***
669      * Does nothing currently
670      */
671     public synchronized void keyReleased(KeyEvent e)
672     {}
673 
674     /***
675      * Does nothing currently
676      */
677     public synchronized void keyTyped(KeyEvent e)
678     {}
679 
680 }