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

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

first version of interaction types for GUI events

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