source: trunk/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/gui/InteractionEventList.java @ 550

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