|
|||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
AbstractEventData.java | 62.5% | 55.9% | 85.2% | 60.8% |
|
1 |
package junit.extensions.jfcunit.eventdata;
|
|
2 |
|
|
3 |
import junit.extensions.jfcunit.JFCTestCase;
|
|
4 |
import junit.extensions.jfcunit.xml.JFCXMLConstants;
|
|
5 |
|
|
6 |
import java.applet.Applet;
|
|
7 |
|
|
8 |
import java.awt.AWTEvent;
|
|
9 |
import java.awt.Component;
|
|
10 |
import java.awt.Point;
|
|
11 |
import java.awt.Rectangle;
|
|
12 |
import java.awt.Window;
|
|
13 |
import java.awt.event.KeyEvent;
|
|
14 |
|
|
15 |
import javax.swing.JComponent;
|
|
16 |
|
|
17 |
|
|
18 |
/**
|
|
19 |
* Abstract data container class that holds most of the
|
|
20 |
* data necessary for jfcUnit to fire events.
|
|
21 |
*
|
|
22 |
* @author <a href="mailto:vraravam@thoughtworks.com">Vijay Aravamudhan : ThoughtWorks Inc.</a>
|
|
23 |
*/
|
|
24 |
public abstract class AbstractEventData implements EventDataConstants { |
|
25 |
/**
|
|
26 |
* The {@link JFCTestCase} on whose thread <code>awtSleep()</code>
|
|
27 |
* has to be invoked.
|
|
28 |
*/
|
|
29 |
private JFCTestCase m_testCase;
|
|
30 |
|
|
31 |
/**
|
|
32 |
* The reference point to place the mouse. Either custom set or
|
|
33 |
* derived from the screen location.
|
|
34 |
*/
|
|
35 |
private Point m_referencePoint;
|
|
36 |
|
|
37 |
/**
|
|
38 |
* The screen location to place the mouse.
|
|
39 |
*/
|
|
40 |
private Point m_screenLocation;
|
|
41 |
|
|
42 |
/**
|
|
43 |
* State of event data. If invalid then data has not been loaded
|
|
44 |
* into the event yet.
|
|
45 |
*/
|
|
46 |
private boolean m_valid; |
|
47 |
|
|
48 |
/**
|
|
49 |
* The modifier key values that need to be passed onto the event.
|
|
50 |
*/
|
|
51 |
private int m_modifiers; |
|
52 |
|
|
53 |
/**
|
|
54 |
* The position to place the mouse within the component.
|
|
55 |
*/
|
|
56 |
private int m_position; |
|
57 |
|
|
58 |
/**
|
|
59 |
* The wait time in ms between each event.
|
|
60 |
*/
|
|
61 |
private long m_sleepTime; |
|
62 |
|
|
63 |
/**
|
|
64 |
* Set the attribute value.
|
|
65 |
*
|
|
66 |
* @param testCase The new value of the attribute
|
|
67 |
*/
|
|
68 | 2193 |
public final void setTestCase(final JFCTestCase testCase) { |
69 | 2193 |
m_testCase = testCase; |
70 |
} |
|
71 |
|
|
72 |
/**
|
|
73 |
* Get the attribute value.
|
|
74 |
*
|
|
75 |
* @return JFCTestCase The value of the attribute
|
|
76 |
*/
|
|
77 | 8179 |
public final JFCTestCase getTestCase() {
|
78 | 8179 |
return m_testCase;
|
79 |
} |
|
80 |
|
|
81 |
/**
|
|
82 |
* The source {@link java.awt.Component} on which the event has
|
|
83 |
* to be fired.
|
|
84 |
*
|
|
85 |
* @return The source {@link java.awt.Component}
|
|
86 |
*/
|
|
87 |
public abstract Component getComponent();
|
|
88 |
|
|
89 |
/**
|
|
90 |
* Get the default position.
|
|
91 |
* @return Default position.
|
|
92 |
*/
|
|
93 | 0 |
public int getDefaultPosition() { |
94 | 0 |
return EventDataConstants.DEFAULT_POSITION;
|
95 |
} |
|
96 |
|
|
97 |
/**
|
|
98 |
* Get the default sleep time.
|
|
99 |
* @return ms sleep time.
|
|
100 |
*/
|
|
101 | 1144 |
public long getDefaultSleepTime() { |
102 | 1144 |
return EventDataConstants.DEFAULT_SLEEPTIME;
|
103 |
} |
|
104 |
|
|
105 |
/**
|
|
106 |
* Get the screen location for the event.
|
|
107 |
* @return Point screen location for the event.
|
|
108 |
*/
|
|
109 | 1818 |
public final Point getLocationOnScreen() {
|
110 | 1818 |
return m_screenLocation;
|
111 |
} |
|
112 |
|
|
113 |
/**
|
|
114 |
* Returns true if the keyCode refers to a meta character.
|
|
115 |
*
|
|
116 |
* @param keyCode code to be checked.
|
|
117 |
* @return boolean true if the keyCode is a meta key.
|
|
118 |
*/
|
|
119 | 1223 |
public final boolean isMetaChar(final int keyCode) { |
120 | 1223 |
switch (keyCode) {
|
121 | 11 |
case KeyEvent.VK_ALT:
|
122 | 0 |
case KeyEvent.VK_ALT_GRAPH:
|
123 | 0 |
case KeyEvent.VK_CAPS_LOCK:
|
124 | 2 |
case KeyEvent.VK_CONTROL:
|
125 | 0 |
case KeyEvent.VK_NUM_LOCK:
|
126 | 0 |
case KeyEvent.VK_META:
|
127 | 24 |
case KeyEvent.VK_SHIFT:
|
128 | 37 |
return true; |
129 |
|
|
130 | 1186 |
default:
|
131 | 1186 |
return false; |
132 |
} |
|
133 |
} |
|
134 |
|
|
135 |
/**
|
|
136 |
* Set the attribute value.
|
|
137 |
*
|
|
138 |
* @param modifiers The new value of the attribute
|
|
139 |
*/
|
|
140 | 3195 |
public void setModifiers(final int modifiers) { |
141 | 3195 |
m_modifiers = modifiers; |
142 |
} |
|
143 |
|
|
144 |
/**
|
|
145 |
* Get the attribute value.
|
|
146 |
*
|
|
147 |
* @return int The value of the attribute
|
|
148 |
*/
|
|
149 | 4311 |
public final int getModifiers() { |
150 | 4311 |
return m_modifiers;
|
151 |
} |
|
152 |
|
|
153 |
/**
|
|
154 |
* Get the default modifiers.
|
|
155 |
* @return default modifiers for the event.
|
|
156 |
*/
|
|
157 |
public abstract int getDefaultModifiers(); |
|
158 |
|
|
159 |
/**
|
|
160 |
* Set the attribute value.
|
|
161 |
* @param position The value of the attribute
|
|
162 |
*/
|
|
163 | 2908 |
public void setPosition(final int position) { |
164 | 2908 |
m_position = position; |
165 |
} |
|
166 |
|
|
167 |
/**
|
|
168 |
* Get the attribute value.
|
|
169 |
* @return int The value of the attribute
|
|
170 |
*/
|
|
171 | 638 |
public int getPosition() { |
172 | 638 |
return m_position;
|
173 |
} |
|
174 |
|
|
175 |
/**
|
|
176 |
* Set the attribute value.
|
|
177 |
* @param referencePoint The value of the attribute
|
|
178 |
*/
|
|
179 | 2817 |
public void setReferencePoint(final Point referencePoint) { |
180 | 2817 |
m_referencePoint = referencePoint; |
181 |
} |
|
182 |
|
|
183 |
/**
|
|
184 |
* Get the attribute value.
|
|
185 |
* @return Point The value of the attribute
|
|
186 |
*/
|
|
187 | 332 |
public Point getReferencePoint() {
|
188 | 332 |
return m_referencePoint;
|
189 |
} |
|
190 |
|
|
191 |
/**
|
|
192 |
* Return the root {@link java.awt.Container} of the
|
|
193 |
* current {@link java.awt.Component}.
|
|
194 |
*
|
|
195 |
* @return The root {@link java.awt.Container}.
|
|
196 |
*/
|
|
197 | 3164 |
public Component getRoot() {
|
198 | 3164 |
return getRoot(getComponent());
|
199 |
} |
|
200 |
|
|
201 |
/**
|
|
202 |
* Return the root {@link java.awt.Container} of the
|
|
203 |
* specified {@link java.awt.Component}.
|
|
204 |
*
|
|
205 |
* @param c The {@link java.awt.Component} to obtain the root for.
|
|
206 |
* @return The root {@link java.awt.Container}.
|
|
207 |
*/
|
|
208 | 5226 |
public Component getRoot(final Component c) {
|
209 | 5226 |
Component applet = null;
|
210 |
|
|
211 | 5226 |
for (Component p = c; p != null; p = p.getParent()) { |
212 | 31881 |
if (p instanceof Window || !p.isLightweight()) { |
213 | 5164 |
return p;
|
214 |
} |
|
215 |
|
|
216 | 26717 |
if (p instanceof Applet) { |
217 | 0 |
applet = p; |
218 |
} |
|
219 |
} |
|
220 |
|
|
221 | 62 |
return applet;
|
222 |
} |
|
223 |
|
|
224 |
/**
|
|
225 |
* Set the attribute value.
|
|
226 |
*
|
|
227 |
* @param sleepTime The new value of the attribute
|
|
228 |
*/
|
|
229 | 3339 |
public void setSleepTime(final long sleepTime) { |
230 | 3339 |
m_sleepTime = sleepTime; |
231 |
} |
|
232 |
|
|
233 |
/**
|
|
234 |
* Get the attribute value.
|
|
235 |
*
|
|
236 |
* @return long The value of the attribute
|
|
237 |
*/
|
|
238 | 265 |
public long getSleepTime() { |
239 | 265 |
return m_sleepTime;
|
240 |
} |
|
241 |
|
|
242 |
// The next set of API's deal with creating event data
|
|
243 |
// Based upon a AWT Event for recording.
|
|
244 |
|
|
245 |
/**
|
|
246 |
* Consume the {@link java.awt.Event}.
|
|
247 |
*
|
|
248 |
* @param ae Event to be consumed.
|
|
249 |
* @return boolean true if the event was consumed.
|
|
250 |
*/
|
|
251 |
public abstract boolean consume(final AWTEvent ae); |
|
252 |
|
|
253 |
/**
|
|
254 |
* Set valid state.
|
|
255 |
*
|
|
256 |
* @param valid true if the event has data configured.
|
|
257 |
*/
|
|
258 | 4762 |
public final void setValid(final boolean valid) { |
259 | 4762 |
this.m_valid = valid;
|
260 |
} |
|
261 |
|
|
262 |
/**
|
|
263 |
* Get the valid state.
|
|
264 |
*
|
|
265 |
* @return boolean true if the event is valid.
|
|
266 |
*/
|
|
267 | 7078 |
public final boolean isValid() { |
268 | 7078 |
return m_valid;
|
269 |
} |
|
270 |
|
|
271 |
/**
|
|
272 |
* Compare to event datas and deterime if they are equal.
|
|
273 |
*
|
|
274 |
* @param o Object to be compared.
|
|
275 |
* @return true if the events are the same.
|
|
276 |
*/
|
|
277 | 134 |
public boolean equals(final Object o) { |
278 | 134 |
if (o == null) { |
279 | 12 |
return false; |
280 |
} |
|
281 |
|
|
282 | 122 |
if (o.getClass() != getClass()) {
|
283 | 12 |
return false; |
284 |
} |
|
285 |
|
|
286 |
// isValid
|
|
287 | 110 |
AbstractEventData data = (AbstractEventData) o; |
288 |
|
|
289 | 110 |
return (data.isValid() == isValid())
|
290 |
&& (data.getComponent() == getComponent()) |
|
291 |
&& (data.getModifiers() == getModifiers()) |
|
292 |
&& (data.getPosition() == getPosition()) |
|
293 |
&& (data.getReferencePoint() == getReferencePoint()); |
|
294 |
} |
|
295 |
|
|
296 |
/**
|
|
297 |
* Returns the hashCode of the contained component.
|
|
298 |
* @return int hashCode.
|
|
299 |
*/
|
|
300 | 0 |
public int hashCode() { |
301 | 0 |
Component comp = getComponent(); |
302 |
|
|
303 | 0 |
if (comp != null) { |
304 | 0 |
return comp.hashCode();
|
305 |
} |
|
306 |
|
|
307 | 0 |
return 1;
|
308 |
} |
|
309 |
|
|
310 |
/**
|
|
311 |
* Populate the Element with the attributes to recreate this
|
|
312 |
* event data.
|
|
313 |
* @param e Element to be populated.
|
|
314 |
*/
|
|
315 | 0 |
public void populate(final org.w3c.dom.Element e) { |
316 | 0 |
if (getPosition() != getDefaultPosition()) {
|
317 | 0 |
String position; |
318 |
|
|
319 | 0 |
switch (getPosition()) {
|
320 | 0 |
case NORTH:
|
321 | 0 |
position = "north";
|
322 |
|
|
323 | 0 |
break;
|
324 |
|
|
325 | 0 |
case SOUTH:
|
326 | 0 |
position = "south";
|
327 |
|
|
328 | 0 |
break;
|
329 |
|
|
330 | 0 |
case EAST:
|
331 | 0 |
position = "east";
|
332 |
|
|
333 | 0 |
break;
|
334 |
|
|
335 | 0 |
case WEST:
|
336 | 0 |
position = "west";
|
337 |
|
|
338 | 0 |
break;
|
339 |
|
|
340 | 0 |
case NORTH_WEST:
|
341 | 0 |
position = "northwest";
|
342 |
|
|
343 | 0 |
break;
|
344 |
|
|
345 | 0 |
case NORTH_EAST:
|
346 | 0 |
position = "northeast";
|
347 |
|
|
348 | 0 |
break;
|
349 |
|
|
350 | 0 |
case SOUTH_WEST:
|
351 | 0 |
position = "southwest";
|
352 |
|
|
353 | 0 |
break;
|
354 |
|
|
355 | 0 |
case SOUTH_EAST:
|
356 | 0 |
position = "southeast";
|
357 |
|
|
358 | 0 |
break;
|
359 |
|
|
360 | 0 |
case CENTER:
|
361 | 0 |
position = "center";
|
362 |
|
|
363 | 0 |
break;
|
364 |
|
|
365 | 0 |
case CUSTOM:
|
366 | 0 |
position = "custom";
|
367 |
|
|
368 | 0 |
break;
|
369 |
|
|
370 | 0 |
case PERCENT:
|
371 | 0 |
position = "percent";
|
372 |
|
|
373 | 0 |
break;
|
374 |
|
|
375 | 0 |
case OFFSET:
|
376 | 0 |
position = "offset";
|
377 |
|
|
378 | 0 |
break;
|
379 |
|
|
380 | 0 |
default:
|
381 | 0 |
position = "" + getPosition();
|
382 |
|
|
383 | 0 |
break;
|
384 |
} |
|
385 |
|
|
386 | 0 |
e.setAttribute(JFCXMLConstants.POSITION, position); |
387 |
} |
|
388 |
|
|
389 | 0 |
if (getModifiers() != getDefaultModifiers()) {
|
390 | 0 |
String txt = getModifierText(); |
391 |
|
|
392 | 0 |
if ((txt != null) && (txt.length() > 0)) { |
393 | 0 |
e.setAttribute(JFCXMLConstants.MODIFIERS, txt); |
394 |
} |
|
395 |
} |
|
396 |
|
|
397 | 0 |
if (getSleepTime() != getDefaultSleepTime()) {
|
398 | 0 |
e.setAttribute(JFCXMLConstants.SLEEPTIME, "" + getSleepTime());
|
399 |
} |
|
400 |
|
|
401 | 0 |
Point p = getReferencePoint(); |
402 |
|
|
403 | 0 |
if (p != null) { |
404 | 0 |
e.setAttribute(JFCXMLConstants.REFERENCE, "" + p.x + "," + p.y); |
405 |
} |
|
406 |
} |
|
407 |
|
|
408 |
/**
|
|
409 |
* Prepare the component to receive the {@link java.awt.Event}
|
|
410 |
* by calling <code>requestFocus()</code> on the {@link java.awt.Component}
|
|
411 |
* and calculating the screen location.
|
|
412 |
*
|
|
413 |
* @return true if the component is ready to receive
|
|
414 |
* the {@link java.awt.Event}.
|
|
415 |
*/
|
|
416 | 82 |
public boolean prepareComponent() { |
417 | 82 |
if (!isValidForProcessing(getComponent())) {
|
418 | 8 |
return false; |
419 |
} |
|
420 |
|
|
421 | 74 |
JFCTestCase testCase = getTestCase(); |
422 |
|
|
423 | 74 |
if (testCase != null) { |
424 |
// try to clear the event queue
|
|
425 | 74 |
testCase.flushAWT(); |
426 |
} |
|
427 |
|
|
428 | 74 |
Rectangle compRect = getComponent().getBounds(); |
429 |
|
|
430 | 74 |
if (testCase != null) { |
431 |
// try to clear the event queue
|
|
432 | 74 |
testCase.flushAWT(); |
433 | 74 |
testCase.pauseAWT(); |
434 |
} |
|
435 |
|
|
436 | 74 |
Point p = calculatePoint(compRect); |
437 |
|
|
438 | 74 |
if (getComponent() instanceof JComponent) { |
439 | 44 |
JComponent c = (JComponent) getComponent(); |
440 | 44 |
Rectangle vis = c.getVisibleRect(); |
441 |
|
|
442 | 44 |
if (!vis.contains(p)) {
|
443 | 3 |
Rectangle newView = new Rectangle(p.x - (int) (vis.width / 2), |
444 |
p.y - (int) (vis.height / 2), vis.width, vis.height);
|
|
445 | 3 |
c.scrollRectToVisible(newView); |
446 |
} |
|
447 |
} |
|
448 |
|
|
449 | 74 |
Point screen = getComponent().getLocationOnScreen(); |
450 | 74 |
screen.translate(p.x, p.y); |
451 | 74 |
setLocationOnScreen(screen); |
452 |
|
|
453 | 74 |
return true; |
454 |
} |
|
455 |
|
|
456 |
/**
|
|
457 |
* Get the String description of the abstract event.
|
|
458 |
*
|
|
459 |
* @return String description of the event.
|
|
460 |
*/
|
|
461 | 141 |
public String toString() {
|
462 | 141 |
StringBuffer buf = new StringBuffer(1000);
|
463 | 141 |
buf.append(getClass().getName()); |
464 |
|
|
465 | 141 |
if (!isValid()) {
|
466 | 0 |
buf.append(" invalid");
|
467 |
|
|
468 | 0 |
return buf.toString();
|
469 |
} |
|
470 |
|
|
471 | 141 |
buf.append(" testCase: " + getTestCase());
|
472 | 141 |
buf.append(" modifiers: " + getModifierText());
|
473 | 141 |
buf.append(" sleepTime: " + m_sleepTime);
|
474 | 141 |
buf.append(" position:" + POSITIONSTRINGS[m_position]);
|
475 | 141 |
buf.append(" refPoint: " + m_referencePoint);
|
476 | 141 |
buf.append(" screenLoc: " + m_screenLocation);
|
477 | 141 |
buf.append(" component: " + getComponent());
|
478 |
|
|
479 | 141 |
return buf.toString();
|
480 |
} |
|
481 |
|
|
482 |
/**
|
|
483 |
* Set the screen location for the event.
|
|
484 |
* @param screenLocation screenLocation for event.
|
|
485 |
*/
|
|
486 | 2392 |
protected final void setLocationOnScreen(final Point screenLocation) { |
487 | 2392 |
m_screenLocation = screenLocation; |
488 |
} |
|
489 |
|
|
490 |
/**
|
|
491 |
* Checks whether a component is valid for processing using jfcUnit.
|
|
492 |
*
|
|
493 |
* @param comp The {@link java.awt.Component} to be tested.
|
|
494 |
* @return boolean specifying whether this component is not
|
|
495 |
* null and is showing.
|
|
496 |
*/
|
|
497 | 1711 |
protected boolean isValidForProcessing(final Component comp) { |
498 | 1711 |
return ((comp != null) && comp.isShowing()); |
499 |
} |
|
500 |
|
|
501 |
/**
|
|
502 |
* A utility method to calculate the {@link java.awt.Point}
|
|
503 |
* at which the events are to be fired based on the position
|
|
504 |
* and reference-point specified.
|
|
505 |
*
|
|
506 |
* @param rect The {@link java.awt.Rectangle} containing the
|
|
507 |
* source component.
|
|
508 |
* @return The new {@link java.awt.Point} at which the mouse
|
|
509 |
* events have to be fired.
|
|
510 |
*/
|
|
511 | 2180 |
protected final Point calculatePoint(final Rectangle rect) {
|
512 |
// if the user has set a specific point or if this
|
|
513 |
// calculation has already been done once, then just return.
|
|
514 | 2180 |
if (m_position == CUSTOM) {
|
515 | 59 |
return new Point(rect.x + m_referencePoint.x, |
516 |
rect.y + m_referencePoint.y); |
|
517 |
} |
|
518 |
|
|
519 | 2121 |
int x = 0;
|
520 | 2121 |
int y = 0;
|
521 |
|
|
522 | 2121 |
if (m_position == PERCENT) {
|
523 | 54 |
x = rect.x + (int) ((rect.width * m_referencePoint.x) / 100);
|
524 | 54 |
y = rect.y + (int) ((rect.height * m_referencePoint.y) / 100);
|
525 |
} else {
|
|
526 |
// Calculate the Y position
|
|
527 | 2067 |
if ((m_position == NORTH)
|
528 |
|| (m_position == NORTH_WEST) |
|
529 |
|| (m_position == NORTH_EAST)) { |
|
530 | 8 |
y = rect.y; |
531 | 2059 |
} else if ((m_position == SOUTH) |
532 |
|| (m_position == SOUTH_WEST) |
|
533 |
|| (m_position == SOUTH_EAST)) { |
|
534 | 9 |
y = rect.y + rect.height; |
535 |
} else {
|
|
536 | 2050 |
y = rect.y + (int) (rect.height / 2);
|
537 |
} |
|
538 |
|
|
539 |
// Calculate the X position
|
|
540 | 2067 |
if ((m_position == WEST)
|
541 |
|| (m_position == NORTH_WEST) |
|
542 |
|| (m_position == SOUTH_WEST)) { |
|
543 | 8 |
x = rect.x; |
544 | 2059 |
} else if ((m_position == EAST) |
545 |
|| (m_position == NORTH_EAST) |
|
546 |
|| (m_position == SOUTH_EAST)) { |
|
547 | 247 |
x = rect.x + rect.width; |
548 |
} else {
|
|
549 | 1812 |
x = rect.x + (int) (rect.width / 2);
|
550 |
} |
|
551 |
} |
|
552 |
|
|
553 | 2121 |
return new Point(x, y); |
554 |
} |
|
555 |
|
|
556 |
/**
|
|
557 |
* Check if this event can consume the {@link java.awt.AWTEvent}.
|
|
558 |
*
|
|
559 |
* @param ae Event to be consumed.
|
|
560 |
* @return boolean true if the event can be consumed.
|
|
561 |
*/
|
|
562 | 0 |
protected boolean canConsume(final AWTEvent ae) { |
563 | 0 |
if (!isValid()) {
|
564 | 0 |
return true; |
565 |
} |
|
566 |
|
|
567 | 0 |
return (ae.getSource().equals(getComponent()));
|
568 |
} |
|
569 |
|
|
570 |
/**
|
|
571 |
* Get the modifier text for the current modifiers.
|
|
572 |
* @return String with modifiers separated by
|
|
573 |
* the +. Ex: Alt+Shift
|
|
574 |
*/
|
|
575 |
abstract String getModifierText(); |
|
576 |
} |
|
577 |
|
|