source: trunk/quest-core-events-patrick/src/main/java/de/ugoe/cs/quest/eventcore/userinteraction/InteractionEventList.java @ 449

Last change on this file since 449 was 449, checked in by pharms, 12 years ago

Initial import.

  • Property svn:executable set to *
File size: 9.3 KB
Line 
1//-------------------------------------------------------------------------------------------------
2// Module    : $RCSfile: InteractionEventList.java,v $
3// Version   : $Revision: 0.0 $  $Author: Patrick $  $Date: 04.12.2011 10:20:14 $
4// Project   : TaskTreePerformanceTest
5// Creation  : 2011 by Patrick
6// Copyright : Patrick Harms, 2011
7//-------------------------------------------------------------------------------------------------
8
9package de.ugoe.cs.quest.eventcore.userinteraction;
10
11import java.util.ArrayList;
12import java.util.Collection;
13import java.util.List;
14
15//-------------------------------------------------------------------------------------------------
16/**
17 * TODO comment
18 *
19 * @version $Revision: $ $Date: $
20 * @author  2011, last modified by $Author: $
21 */
22//-------------------------------------------------------------------------------------------------
23@SuppressWarnings("serial")
24public class InteractionEventList
25  extends ArrayList<InteractionEvent>
26  implements List<InteractionEvent>
27{
28  /** stores the events to be handled later in the order, they should be processed */
29  private List<KeyEventPair> mEventPairs = new ArrayList<KeyEventPair>();
30 
31  //-----------------------------------------------------------------------------------------------
32  /**
33   * this method sorts interaction events for pressed keys. The reason is, that sometimes the
34   * release of one key comes after the pressing of the succeeding key. This only makes sense
35   * for shift, ctrl or alt keys, but not for usual characters. So the events are sorted.<br/>
36   * Furthermore, this methods creates key released events in the specific case, where a key is
37   * pressed for a long time. Here, many subsequent key pressed events for the same key can be
38   * observed, for which there are no key released events.
39   */
40  //-----------------------------------------------------------------------------------------------
41  @Override
42  public boolean add(InteractionEvent event)
43  {
44    if (event.getInteraction() instanceof KeyInteraction)
45    {
46      for (int i = 0; i < mEventPairs.size(); i++)
47      {
48        KeyEventPair eventPair = mEventPairs.get(i);
49       
50        if (eventPair.process(event))
51        {
52          // handle all leading and completed event pairs, if any
53          while ((mEventPairs.size() > 0) && (mEventPairs.get(0).isComplete()))
54          {
55            addEventPair(mEventPairs.get(0));
56            mEventPairs.remove(0);
57          }
58          return true;
59        }
60      }
61     
62      mEventPairs.add(new KeyEventPair(event));
63      return true;
64    }
65    else
66    {
67      // any other event is simply added
68      return super.add(event);
69    }
70  }
71
72  //-----------------------------------------------------------------------------------------------
73  /* (non-Javadoc)
74   * @see java.util.ArrayList#add(int, java.lang.Object)
75   */
76  //-----------------------------------------------------------------------------------------------
77  @Override
78  public void add(int index, InteractionEvent event)
79  {
80    List<InteractionEvent> remaining = new ArrayList<InteractionEvent>();
81   
82    while (index < super.size())
83    {
84      remaining.add(super.remove(index));
85    }
86   
87    add(event);
88    addAll(remaining);
89  }
90
91  //-----------------------------------------------------------------------------------------------
92  /* (non-Javadoc)
93   * @see java.util.ArrayList#addAll(java.util.Collection)
94   */
95  //-----------------------------------------------------------------------------------------------
96  @Override
97  public boolean addAll(Collection<? extends InteractionEvent> events)
98  {
99    int initialSize = super.size();
100   
101    for (InteractionEvent event : events)
102    {
103      add(event);
104    }
105   
106    return initialSize != super.size();
107  }
108
109  //-----------------------------------------------------------------------------------------------
110  /* (non-Javadoc)
111   * @see java.util.ArrayList#addAll(int, java.util.Collection)
112   */
113  //-----------------------------------------------------------------------------------------------
114  @Override
115  public boolean addAll(int index, Collection<? extends InteractionEvent> events)
116  {
117    int initialSize = super.size();
118   
119    List<InteractionEvent> remaining = new ArrayList<InteractionEvent>();
120   
121    while (index < super.size())
122    {
123      remaining.add(super.remove(index));
124    }
125   
126    addAll(events);
127    addAll(remaining);
128   
129    return initialSize != super.size();
130  }
131
132  //-----------------------------------------------------------------------------------------------
133  /**
134   *
135   */
136  //-----------------------------------------------------------------------------------------------
137  private void addEventPair(KeyEventPair eventPair)
138  {
139    super.add(eventPair.mFirst);
140   
141    for (KeyEventPair child : eventPair.mChildren)
142    {
143      addEventPair(child);
144    }
145   
146    super.add(eventPair.mSecond);
147  }
148
149  //-----------------------------------------------------------------------------------------------
150  /**
151   *
152   */
153  //-----------------------------------------------------------------------------------------------
154  private static class KeyEventPair
155  {
156    /** the first interaction event */
157    private InteractionEvent mFirst;
158   
159    /** the second interaction event */
160    private InteractionEvent mSecond;
161
162    /** the children, this event pair may have */
163    private List<KeyEventPair> mChildren = new ArrayList<KeyEventPair>();
164   
165    //---------------------------------------------------------------------------------------------
166    /**
167     *
168     */
169    //---------------------------------------------------------------------------------------------
170    private KeyEventPair(InteractionEvent first)
171    {
172      if (!(first.getInteraction() instanceof KeyPressed))
173      {
174        throw new IllegalArgumentException
175          ("can only handle key pressed interaction events as first element of an event pair");
176      }
177      mFirst = first;
178    }
179   
180    //---------------------------------------------------------------------------------------------
181    /**
182     * sorts the event as the second of the pair or as the closing of this. Returns true,
183     * if this matched, false else
184     */
185    //---------------------------------------------------------------------------------------------
186    private boolean process(InteractionEvent event)
187    {
188      if (!(event.getInteraction() instanceof KeyInteraction))
189      {
190        throw new IllegalArgumentException("can only handle key interaction events");
191      }
192     
193      if (this.isComplete())
194      {
195        // do not process events, if there are no more events expected
196        return false;
197      }
198     
199      if ((event.getInteraction() instanceof KeyReleased) &&
200          (((KeyInteraction) mFirst.getInteraction()).getKey() ==
201           ((KeyInteraction) event.getInteraction()).getKey()) &&
202          (mSecond == null))
203      {
204        // this is the release of the represented key. Store it and notify the processing.
205        mSecond = event;
206        return true;
207      }
208      else if ((event.getInteraction() instanceof KeyPressed) &&
209               (((KeyInteraction) mFirst.getInteraction()).getKey() ==
210                ((KeyInteraction) event.getInteraction()).getKey()) &&
211               (mSecond == null))
212      {
213        // the key was pressed before it was released again. This happens, if the key
214        // stays pressed for a long time. Generate a key released event but do not mark
215        // the new event as processed
216        mSecond = new InteractionEvent
217          (mFirst.getGUIElement(),
218           new KeyReleased(((KeyInteraction) event.getInteraction()).getKey()));
219        return false;
220      }
221      else if (((KeyInteraction) mFirst.getInteraction()).getKey().isCombinationKey() &&
222               (((KeyInteraction) mFirst.getInteraction()).getKey() !=
223                ((KeyInteraction) event.getInteraction()).getKey()))
224      {
225        // this pair may have children. Let the event be processed by the children. If this
226        // doesn't work, add the event as a new child pair, if it is a new key pressed
227       
228        for (KeyEventPair child : mChildren)
229        {
230          if (child.process(event))
231          {
232            return true;
233          }
234        }
235       
236        if (event.getInteraction() instanceof KeyPressed)
237        {
238          mChildren.add(new KeyEventPair(event));
239          return true;
240        }
241        else
242        {
243          return false;
244        }
245      }
246      else
247      {
248        // this pair may not have children
249        return false;
250      }
251    }
252   
253    //---------------------------------------------------------------------------------------------
254    /**
255     * @return
256     */
257    //---------------------------------------------------------------------------------------------
258    private boolean isComplete()
259    {
260      if ((mFirst != null) && (mSecond != null))
261      {
262        for (KeyEventPair child : mChildren)
263        {
264          if (!child.isComplete())
265          {
266            return false;
267          }
268        }
269       
270        return true;
271      }
272      else
273      {
274        return false;
275      }
276    }
277
278  }
279}
Note: See TracBrowser for help on using the repository browser.