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 }