1 package com.explosion.expf;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
149
150
151 if (actionsHandledByThisListener.get(command) == null)
152 {
153 log.debug("Event not handled by CompoundListener, delegating to locals and globals.");
154
155
156
157
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
246
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
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
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
635 if (helpInternalFrame != null && !helpEmbedded)
636 {
637
638 if (helpInternalFrame.isVisible())
639 showing = true;
640
641
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 }