View Javadoc

1   /*
2    * Copyright 2006-2025 The JGUIraffe Team.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License")
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package net.sf.jguiraffe.gui.platform.swing.builder.event;
17  
18  import java.awt.event.ActionListener;
19  import java.awt.event.FocusListener;
20  import java.awt.event.MouseListener;
21  import java.util.EventListener;
22  import java.util.HashMap;
23  import java.util.Map;
24  
25  import net.sf.jguiraffe.gui.builder.event.FormEventManager;
26  import net.sf.jguiraffe.gui.builder.event.FormListenerType;
27  import net.sf.jguiraffe.gui.builder.event.PlatformEventManager;
28  import net.sf.jguiraffe.gui.forms.ComponentHandler;
29  
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  
33  /**
34   * <p>
35   * Swing specific implementation of the <code>PlatformEventManager</code>
36   * interface.
37   * </p>
38   * <p>
39   * This class provides functionality for registering event listeners at Swing
40   * components. It can deal with <code>ComponentHandler</code> objects have been
41   * created by the Swing-specific implementation of the
42   * <code>ComponentManager</code> interface; especially they must implement the
43   * {@link SwingEventSource} interface. Other {@code ComponentHandler} objects
44   * are silently ignored.
45   * </p>
46   * <p>
47   * The Swing-specific implementation of events relies on some features of the
48   * {@link FormEventManager} class:
49   * <ul>
50   * <li>Registration and unregistration of event listeners are synchronized for
51   * the same event listener types (i.e. there won't be concurrent calls of
52   * <code>registerListener()</code> and/or <code>unregisterListener()</code> for
53   * the same listener type).</li>
54   * <li>Each component is added only a single event listener of the same type
55   * (multiplexing of event listeners is done by the <code>FormEventManager</code>
56   * )</li>
57   * </ul>
58   * </p>
59   *
60   * @author Oliver Heger
61   * @version $Id: SwingEventManager.java 205 2012-01-29 18:29:57Z oheger $
62   */
63  public class SwingEventManager implements PlatformEventManager
64  {
65      /** The logger. */
66      private final Log log = LogFactory.getLog(getClass());
67  
68      /** Stores a map with the so far registered event adapters. */
69      private final Map<FormListenerType, Map<String, EventListener>> registeredListeners;
70  
71      /**
72       * Creates a new instance of <code>SwingEventManager</code>.
73       */
74      public SwingEventManager()
75      {
76          registeredListeners = new HashMap<FormListenerType, Map<String, EventListener>>();
77          for (FormListenerType type : FormListenerType.values())
78          {
79              Map<String, EventListener> typeListeners = new HashMap<String, EventListener>();
80              registeredListeners.put(type, typeListeners);
81          }
82      }
83  
84      /**
85       * Registers the event manager as an event listener at the specified
86       * component.
87       *
88       * @param name the component's name
89       * @param handler the component handler
90       * @param eventManager the event manager
91       * @param type the listener type
92       */
93      public void registerListener(String name, ComponentHandler<?> handler,
94              FormEventManager eventManager, FormListenerType type)
95      {
96          if (type == null)
97          {
98              throw new IllegalArgumentException(
99                      "Listener type must not be null!");
100         }
101         SwingEventSource source = obtainSource(handler);
102         if (source == null)
103         {
104             return;
105         }
106         EventListener listener = null;
107 
108         switch (type)
109         {
110         case ACTION:
111             ActionListener al = new ActionEventAdapter(eventManager, handler,
112                     name);
113             source.addActionListener(al);
114             listener = al;
115             break;
116 
117         case CHANGE:
118             ChangeListener cl = new ChangeEventAdapter(eventManager, handler,
119                     name);
120             source.addChangeListener(cl);
121             listener = cl;
122             break;
123 
124         case FOCUS:
125             FocusListener fl = new FocusEventAdapter(eventManager, handler,
126                     name);
127             source.addFocusListener(fl);
128             listener = fl;
129             break;
130 
131         default:  // must be type MOUSE
132             MouseListener ml = new MouseEventAdapter(eventManager, handler,
133                     name);
134             source.addMouseListener(ml);
135             listener = ml;
136             break;
137         }
138 
139         registeredListeners.get(type).put(name, listener);
140     }
141 
142     /**
143      * Unregisters the event listener from the specified component.
144      *
145      * @param name the component's name
146      * @param handler the component handler
147      * @param eventManager the event manager
148      * @param type the listener type
149      */
150     public void unregisterListener(String name, ComponentHandler<?> handler,
151             FormEventManager eventManager, FormListenerType type)
152     {
153         if (type == null)
154         {
155             throw new IllegalArgumentException(
156                     "Listener type must not be null!");
157         }
158         SwingEventSource source = obtainSource(handler);
159         if (source == null)
160         {
161             return;
162         }
163         EventListener l = registeredListeners.get(type).remove(name);
164         assert l != null : "Try to remove non existing listener!";
165 
166         switch (type)
167         {
168         case ACTION:
169             source.removeActionListener((ActionListener) l);
170             break;
171         case CHANGE:
172             source.removeChangeListener((ChangeListener) l);
173             break;
174         case FOCUS:
175             source.removeFocusListener((FocusListener) l);
176             break;
177         default:  // must be type MOUSE
178             source.removeMouseListener((MouseListener) l);
179             break;
180         }
181     }
182 
183     /**
184      * Obtains the {@code SwingEventSource} for the given component handler.
185      * This method checks whether the handler is supported. If this is the case,
186      * it can be casted to an event source. Otherwise, <b>null</b> is returned.
187      *
188      * @param handler the {@code ComponentHandler}
189      * @return the corresponding {@code SwingEventSource} or <b>null</b>
190      */
191     private SwingEventSource obtainSource(ComponentHandler<?> handler)
192     {
193         if (handler instanceof SwingEventSource)
194         {
195             return (SwingEventSource) handler;
196         }
197 
198         if (log.isDebugEnabled())
199         {
200             log.debug("Component handler is no SwingEventSource: " + handler
201                     + ". Ignoring.");
202         }
203         return null;
204     }
205 }