/src/org/mt4j/input/GestureEventSupport.java

http://mt4j.googlecode.com/ · Java · 270 lines · 122 code · 47 blank · 101 comment · 47 complexity · c75c7b56256998f522ccaa985b21b64e MD5 · raw file

  1. /***********************************************************************
  2. * mt4j Copyright (c) 2008 - 2009 Christopher Ruff, Fraunhofer-Gesellschaft All rights reserved.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. ***********************************************************************/
  18. package org.mt4j.input;
  19. import java.util.*;
  20. import java.util.Map.Entry;
  21. import org.mt4j.input.inputProcessors.IGestureEventListener;
  22. import org.mt4j.input.inputProcessors.IInputProcessor;
  23. import org.mt4j.input.inputProcessors.MTGestureEvent;
  24. public class GestureEventSupport {
  25. // private List<IGestureEventListener> gestureListeners;
  26. /** The gestureEvtSenders to listener. */
  27. private Map<Class<? extends IInputProcessor>, IGestureEventListener[]> gestureSenderToGestureListener;
  28. /** The Constant EMPTY. */
  29. private static final IGestureEventListener[] EMPTY = {};
  30. public GestureEventSupport() {
  31. super();
  32. // this.gestureListeners = new ArrayList<IGestureEventListener>();
  33. }
  34. // /**
  35. // * Constructs a <code>PropertyChangeSupport</code> object.
  36. // *
  37. // * @param sourceBean The bean to be given as the source for any events.
  38. // */
  39. // public GestureEventSupport(Object sourceBean) {
  40. // if (sourceBean == null) {
  41. // throw new NullPointerException();
  42. // }
  43. // source = sourceBean;
  44. // }
  45. /**
  46. * Add a gestureEvtSenderChangeListener to the listener map.
  47. * If <code>listener</code> is null, no exception is thrown and no action
  48. * is taken.
  49. *
  50. * @param gestureEvtSender the gestureEvtSender
  51. * @param listener The gestureEvtSenderChangeListener to be added
  52. */
  53. public synchronized void addGestureEvtListener(Class<? extends IInputProcessor> gestureEvtSender, IGestureEventListener listener) {
  54. if (listener == null) {
  55. return;
  56. }
  57. this.lazyInitializeMap();
  58. IGestureEventListener[] array = this.gestureSenderToGestureListener.get(gestureEvtSender);
  59. //Add listener to array
  60. int size = (array != null) ? array.length : 0;
  61. IGestureEventListener[] clone = newArray(size + 1);
  62. clone[size] = listener;
  63. if (array != null) {
  64. System.arraycopy(array, 0, clone, 0, size);
  65. }
  66. //Put new listener array into map
  67. this.gestureSenderToGestureListener.put(gestureEvtSender, clone);
  68. }
  69. /**
  70. * Creates a new array of listeners of the specified size.
  71. *
  72. * @param length the length
  73. *
  74. * @return the gestureEvtSender change listener[]
  75. */
  76. protected IGestureEventListener[] newArray(int length) {
  77. return (0 < length) ? new IGestureEventListener[length] : EMPTY;
  78. }
  79. /**
  80. * Removes a IGestureEventListener to the listener map.
  81. * Throws no error if the listener isnt found.
  82. *
  83. * @param gestureEvtSender the gestureEvtSender
  84. * @param listener the listener
  85. */
  86. public synchronized void removeGestureEventListener(Class<? extends IInputProcessor> gestureEvtSender, IGestureEventListener listener) {
  87. if (listener == null || gestureEvtSender == null) {
  88. return;
  89. }
  90. this.lazyInitializeMap();
  91. if (this.gestureSenderToGestureListener != null) {
  92. IGestureEventListener[] array = this.gestureSenderToGestureListener.get(gestureEvtSender);
  93. if (array != null) {
  94. for (int i = 0; i < array.length; i++) {
  95. if (listener.equals(array[i])) {
  96. int size = array.length - 1;
  97. if (size > 0) {
  98. IGestureEventListener[] clone = newArray(size);
  99. System.arraycopy(array, 0, clone, 0, i);
  100. System.arraycopy(array, i + 1, clone, i, size - i);
  101. this.gestureSenderToGestureListener.put(gestureEvtSender, clone);
  102. }
  103. else {
  104. this.gestureSenderToGestureListener.remove(gestureEvtSender);
  105. if (this.gestureSenderToGestureListener.isEmpty()) {
  106. this.gestureSenderToGestureListener = null;
  107. }
  108. }
  109. break;
  110. }
  111. }
  112. }
  113. }
  114. }
  115. /**
  116. * Clear listeners.
  117. */
  118. public synchronized void clearListeners(){
  119. if (this.gestureSenderToGestureListener == null){
  120. return;
  121. }
  122. this.lazyInitializeMap();
  123. this.gestureSenderToGestureListener.clear();
  124. }
  125. /**
  126. * Fire an existing GestureEvent to any registered listeners.
  127. *
  128. * @param evt The GestureEvent object.
  129. */
  130. public void fireGestureEvt(MTGestureEvent evt) {
  131. if (this.gestureSenderToGestureListener != null
  132. && !this.gestureSenderToGestureListener.isEmpty()
  133. ){
  134. // Class<? extends GestureEventFireMarker> gestureEvtSenderName = evt.getgestureEvtSender();
  135. Class<? extends IInputProcessor> marker = evt.getSource().getClass();
  136. IGestureEventListener[] common = this.gestureSenderToGestureListener.get(null);
  137. IGestureEventListener[] named = (marker != null) ? this.gestureSenderToGestureListener.get(marker) : null;
  138. this.fire(common, evt);
  139. this.fire(named, evt);
  140. }
  141. }
  142. /**
  143. * Fires the events to the listeners.
  144. *
  145. * @param listeners the listeners
  146. * @param event the event
  147. */
  148. private void fire(IGestureEventListener[] listeners, MTGestureEvent event) {
  149. if (listeners != null) {
  150. for (IGestureEventListener listener : listeners) {
  151. listener.processGestureEvent(event);
  152. }
  153. }
  154. }
  155. /**
  156. * Returns all listeners in the map.
  157. *
  158. * @return an array of all listeners
  159. */
  160. public final synchronized IGestureEventListener[] getListeners() {
  161. if (this.gestureSenderToGestureListener == null) {
  162. return newArray(0);
  163. }
  164. List<IGestureEventListener> list = new ArrayList<IGestureEventListener>();
  165. IGestureEventListener[] listeners = this.gestureSenderToGestureListener.get(null);
  166. if (listeners != null) {
  167. list.addAll(Arrays.asList(listeners));
  168. //for (IGestureEventListener listener : listeners) {
  169. // list.add(listener);
  170. //}
  171. }
  172. for (Entry<Class<? extends IInputProcessor>, IGestureEventListener[]> entry : this.gestureSenderToGestureListener.entrySet()) {
  173. Class<? extends IInputProcessor> gestureEvtSender = entry.getKey();
  174. if (gestureEvtSender != null) {
  175. list.addAll(Arrays.asList(entry.getValue()));
  176. //for (IGestureEventListener listener : entry.getValue()) {
  177. // list.add(listener);
  178. //}
  179. }
  180. }
  181. return list.toArray(newArray(list.size()));
  182. }
  183. /**
  184. * Returns listeners that have been associated with the named gestureEvtSender.
  185. *
  186. * @param gestureEvtSender the name of the property
  187. *
  188. * @return an array of listeners for the named property
  189. */
  190. public final IGestureEventListener[] getListeners(Class<? extends IInputProcessor> gestureEvtSender) {
  191. if (gestureEvtSender != null) {
  192. IGestureEventListener[] listeners = this.gestureSenderToGestureListener.get(gestureEvtSender);
  193. if (listeners != null) {
  194. return listeners.clone();
  195. }
  196. }
  197. return newArray(0);
  198. }
  199. /**
  200. * Indicates whether the map contains
  201. * at least one listener to be notified.
  202. *
  203. * @param gestureEvtSender the gestureEvtSender
  204. *
  205. * @return {@code true} if at least one listener exists or
  206. * {@code false} otherwise
  207. */
  208. public final synchronized boolean hasListeners(Class<? extends IInputProcessor> gestureEvtSender) {
  209. if (this.gestureSenderToGestureListener == null) {
  210. return false;
  211. }
  212. IGestureEventListener[] array = this.gestureSenderToGestureListener.get(null);
  213. return (array != null) || ((gestureEvtSender != null) && (null != this.gestureSenderToGestureListener.get(gestureEvtSender)));
  214. }
  215. /**
  216. * Checks if the map is null and then lazily initializes it.
  217. */
  218. private void lazyInitializeMap(){
  219. if (gestureSenderToGestureListener == null){
  220. gestureSenderToGestureListener = new HashMap<Class<? extends IInputProcessor>, IGestureEventListener[]>();
  221. }
  222. }
  223. }