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

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