001: /*
002: * Jacareto Copyright (c) 2002-2005
003: * Applied Computer Science Research Group, Darmstadt University of
004: * Technology, Institute of Mathematics & Computer Science,
005: * Ludwigsburg University of Education, and Computer Based
006: * Learning Research Group, Aachen University. All rights reserved.
007: *
008: * Jacareto is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * Jacareto is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public
019: * License along with Jacareto; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: *
022: */
023:
024: package jacareto.catching;
025:
026: import jacareto.comp.Components;
027: import jacareto.eventmask.AWTEventMask;
028: import jacareto.record.ActionEventRecordable;
029: import jacareto.record.ComponentEventRecordable;
030: import jacareto.record.FocusEventRecordable;
031: import jacareto.record.ItemEventRecordable;
032: import jacareto.record.KeyEventRecordable;
033: import jacareto.record.MouseEventRecordable;
034: import jacareto.record.Record;
035: import jacareto.record.RecordException;
036: import jacareto.record.WindowEventRecordable;
037: import jacareto.system.Environment;
038: import jacareto.toolkit.TimeSpanCalculator;
039:
040: import java.awt.event.ActionEvent;
041: import java.awt.event.ComponentEvent;
042: import java.awt.event.FocusEvent;
043: import java.awt.event.ItemEvent;
044: import java.awt.event.KeyEvent;
045: import java.awt.event.MouseEvent;
046: import java.awt.event.WindowEvent;
047:
048: import java.util.EventObject;
049:
050: /**
051: * <p>
052: * Saves events dispatched by the AWT event queue to a specified record. (More precise: Not the
053: * events itself but recordables representing the events)
054: * </p>
055: *
056: * <p>
057: * The record will not be opened or closed by this instance. It must be opened outside.
058: * </p>
059: *
060: * @author Thomas Leonhardt
061: * @author <a href="mailto:cspannagel@web.de">Christian Spannagel</a> (Version 1.1)
062: * @version 1.13
063: */
064: public class AWTEventRecorder extends Catcher {
065: /** The record this instance writes to. */
066: private Record eventRecord;
067:
068: /** The instance which knows the components. */
069: private Components components;
070:
071: /** The time span calculator for calculation of the relative time to the last recorded event. */
072: private TimeSpanCalculator timeSpanCalculator;
073:
074: /** The code of a last modifier key event which has been catched. */
075: private int codeOfLastModifierKeyCatched;
076:
077: /**
078: * Creates a new AWT event recorder object. The record will not be opened or closed by this
079: * instance.
080: *
081: * @param env the environment
082: * @param eventMask the event mask
083: * @param eventRecord the record where all events should be recorded to
084: * @param components the instance which knows the components
085: */
086: public AWTEventRecorder(Environment env, AWTEventMask eventMask,
087: Record eventRecord, Components components) {
088: super (env, eventMask);
089: setRecord(eventRecord);
090: setComponents(components);
091: }
092:
093: /**
094: * Starts listening to events.
095: */
096: public void start() {
097: super .start();
098: timeSpanCalculator.start();
099: codeOfLastModifierKeyCatched = 0;
100: getLogger().debug(
101: getLanguage().getString(
102: "Catching.EventRecorder.Msg.Start"));
103: }
104:
105: /**
106: * Stops listening to events.
107: */
108: public void stop() {
109: super .stop();
110: timeSpanCalculator.stop();
111: codeOfLastModifierKeyCatched = 0;
112: getLogger().debug(
113: getLanguage().getString(
114: "Catching.EventRecorder.Msg.Stop"));
115: }
116:
117: /**
118: * Returns whether or not this catcher is interested in the given event object which is not an
119: * AWT event.
120: *
121: * @param event EventObject
122: *
123: * @return true, if Catcher handles event
124: */
125: public boolean handlesEventObject(EventObject event) {
126: // Component events are only included for capturing "window moved" and "window resized"
127: // events. Because registering an event listener for all component events at the AWTEventQueue
128: // causes many problems (BlueJ hangs up, for example), component events are captured only
129: // for windows via the separate EventQueue of Jacareto.
130: return (event instanceof ComponentEvent);
131: }
132:
133: /**
134: * Writes a recordable representing the dispatched event to the record (if the event is
135: * included in the event mask of this instance and the instance is listening to events).
136: * Completely rewritten in version 1.1
137: *
138: * @param event the event
139: *
140: * @return always <code>true</code> (other listeners should also get the event)
141: */
142: public boolean handleEvent(EventObject event) {
143: try {
144: if (event instanceof MouseEvent) {
145: eventRecord.record(new MouseEventRecordable(env,
146: (MouseEvent) event, components,
147: getTimeSinceLastEvent(), 0));
148: } else if (event instanceof KeyEvent) {
149: // Don't catch sequences when a modifier key like SHIFT is pressed over a long period
150: KeyEvent keyEvent = (KeyEvent) event;
151: int keyCode = keyEvent.getKeyCode();
152: int id = keyEvent.getID();
153: boolean isModifiingKey = (keyCode == KeyEvent.VK_CONTROL)
154: || (keyCode == KeyEvent.VK_ALT)
155: || (keyCode == KeyEvent.VK_ALT_GRAPH)
156: || (keyCode == KeyEvent.VK_META)
157: || (keyCode == KeyEvent.VK_SHIFT);
158:
159: if (isModifiingKey) {
160: if (keyCode != codeOfLastModifierKeyCatched) {
161: if (id == KeyEvent.KEY_PRESSED) {
162: codeOfLastModifierKeyCatched = keyCode;
163: }
164: } else {
165: if (id == KeyEvent.KEY_PRESSED) {
166: return true;
167: } else if (id == KeyEvent.KEY_RELEASED) {
168: codeOfLastModifierKeyCatched = 0;
169: }
170: }
171: }
172:
173: eventRecord.record(new KeyEventRecordable(env,
174: (KeyEvent) event, components,
175: getTimeSinceLastEvent(), 0));
176: } else if (event instanceof ActionEvent) {
177: eventRecord.record(new ActionEventRecordable(env,
178: (ActionEvent) event, components,
179: getTimeSinceLastEvent(), 0));
180: } else if (event instanceof FocusEvent) {
181: eventRecord.record(new FocusEventRecordable(env,
182: (FocusEvent) event, components,
183: getTimeSinceLastEvent(), 0));
184: } else if (event instanceof WindowEvent) {
185: eventRecord.record(new WindowEventRecordable(env,
186: (WindowEvent) event, components,
187: getTimeSinceLastEvent(), 0));
188: } else if (event instanceof ItemEvent) {
189: eventRecord.record(new ItemEventRecordable(env,
190: (ItemEvent) event, components,
191: getTimeSinceLastEvent(), 0));
192: } else if (event instanceof ComponentEvent) {
193: eventRecord.record(new ComponentEventRecordable(env,
194: (ComponentEvent) event, components,
195: getTimeSinceLastEvent(), 0));
196: }
197:
198: //else if ( event instanceof ContainerEvent ) {
199: //eventRecord.record ( new ContainerEventRecordable (env, (ContainerEvent) event, components, getTimeSinceLastEvent()) );
200: //}
201: } catch (RecordException l) {
202: getLogger().error(l);
203: }
204:
205: return true;
206: }
207:
208: /**
209: * Registers the time span calculator
210: *
211: * @param timeSpanCalculator the time span calculator
212: */
213: public void setTimeSpanCalculator(
214: TimeSpanCalculator timeSpanCalculator) {
215: this .timeSpanCalculator = timeSpanCalculator;
216: }
217:
218: /**
219: * Returns the time span calculator
220: *
221: * @return the time span calculator
222: */
223: public TimeSpanCalculator getTimeSpanCalculator() {
224: return timeSpanCalculator;
225: }
226:
227: /**
228: * Returns the event record.
229: *
230: * @return the event record this instance writes to
231: */
232: public Record getRecord() {
233: return eventRecord;
234: }
235:
236: /**
237: * Sets the event record.
238: *
239: * @param eventRecord the new event record
240: */
241: public void setRecord(Record eventRecord) {
242: this .eventRecord = eventRecord;
243: }
244:
245: /**
246: * Returns the instance which knows the components.
247: *
248: * @return see above :-)
249: */
250: public Components getComponents() {
251: return components;
252: }
253:
254: /**
255: * Sets the instance which knows the components.
256: *
257: * @param components the components instance
258: */
259: public void setComponents(Components components) {
260: this .components = components;
261: }
262:
263: /**
264: * Returns the time since the last event has been recorded.
265: *
266: * @return the time, in msec
267: */
268: public long getTimeSinceLastEvent() {
269: long result = 0;
270:
271: try {
272: result = timeSpanCalculator.getTimeSinceLastReset();
273: timeSpanCalculator.reset();
274: } catch (NullPointerException n) {
275: getLogger().error(
276: getLanguage().getString(
277: "Catching.EventRecorder.Error.NoTSCalc"));
278: }
279:
280: return result;
281: }
282: }
|