Skip to content

Commit c793026

Browse files
committed
Test the AWTInputEventDispatcher
For now, we just test one dispatch of a KeyEvent. But this proves that it fundamentally works. And infrastructure now exists to add more tests easily.
1 parent 88e95fd commit c793026

File tree

2 files changed

+169
-0
lines changed

2 files changed

+169
-0
lines changed

pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,5 +108,13 @@ Institute of Molecular Cell Biology and Genetics.</license.copyrightOwners>
108108
<artifactId>miglayout-swing</artifactId>
109109
<version>${miglayout-swing.version}</version>
110110
</dependency>
111+
112+
<!-- Test dependencies -->
113+
<dependency>
114+
<groupId>junit</groupId>
115+
<artifactId>junit</artifactId>
116+
<scope>test</scope>
117+
</dependency>
111118
</dependencies>
119+
112120
</project>
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2025 SciJava developers.
6+
* %%
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following disclaimer in the documentation
14+
* and/or other materials provided with the distribution.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
* #L%
28+
*/
29+
30+
package org.scijava.ui.awt;
31+
32+
import org.junit.Test;
33+
34+
import java.awt.EventQueue;
35+
import java.awt.Frame;
36+
import java.awt.Panel;
37+
import java.awt.event.*;
38+
import java.lang.reflect.Method;
39+
import java.lang.reflect.Proxy;
40+
import java.util.ArrayList;
41+
import java.util.List;
42+
43+
import org.scijava.display.Display;
44+
import org.scijava.display.event.input.KyPressedEvent;
45+
import org.scijava.event.EventService;
46+
47+
import static org.junit.Assert.assertEquals;
48+
import static org.junit.Assert.assertFalse;
49+
import static org.junit.Assert.assertNotNull;
50+
import static org.junit.Assert.assertTrue;
51+
52+
/**
53+
* Tests {@link AWTInputEventDispatcher}.
54+
*
55+
* @author Curtis Rueden
56+
*/
57+
public class AWTInputEventDispatcherTest {
58+
59+
@Test
60+
public void testKeyPressedEvent() {
61+
AWTInputEventDispatcher dispatcher = dispatcher();
62+
63+
// Dispatch an AWT KeyEvent.
64+
KeyEvent awtEvent = new KeyEvent(new Panel(),
65+
KeyEvent.KEY_PRESSED, 0,
66+
InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK,
67+
KeyEvent.VK_0, '0');
68+
dispatcher.keyPressed(awtEvent);
69+
70+
// Verify that KeyEvent was published as a KyEvent.
71+
KyPressedEvent sjEvent = extractEvent(KyPressedEvent.class);
72+
System.out.println(sjEvent.getAccelerator());
73+
assertEquals("control shift NUM0", sjEvent.getAccelerator().toString());
74+
}
75+
76+
private AWTInputEventDispatcher dispatcher() {
77+
return new AWTInputEventDispatcher(mock(Display.class), mock(EventService.class));
78+
}
79+
80+
private static class MethodCall {
81+
Object obj;
82+
Method method;
83+
Object[] args;
84+
MethodCall(Object obj, Method method, Object[] args) {
85+
this.obj = obj;
86+
this.method = method;
87+
this.args = args;
88+
}
89+
}
90+
91+
private final List<MethodCall> calls = new ArrayList<>();
92+
93+
@SuppressWarnings("unchecked")
94+
private <T> T mock(Class<T> iface) {
95+
return (T) Proxy.newProxyInstance(
96+
getClass().getClassLoader(),
97+
new Class<?>[] {iface},
98+
(obj, method, args) -> {
99+
calls.add(new MethodCall(obj, method, args));
100+
return null;
101+
}
102+
);
103+
}
104+
105+
private <T> T extractEvent(Class<T> eventClass) {
106+
assertFalse(calls.isEmpty());
107+
MethodCall call = calls.get(0);
108+
assertNotNull(call);
109+
assertNotNull(call.args);
110+
assertEquals(1, call.args.length);
111+
Object arg = call.args[0];
112+
assertTrue(eventClass.isInstance(arg));
113+
@SuppressWarnings("unchecked")
114+
T typedArg = (T) arg;
115+
calls.clear();
116+
return typedArg;
117+
}
118+
119+
public static void main(String... args) {
120+
EventQueue.invokeLater(() -> {
121+
Frame f = new Frame();
122+
Panel p = new Panel();
123+
f.add(p);
124+
125+
f.addWindowListener(new WindowAdapter() {
126+
@Override public void windowClosing(WindowEvent e) { f.dispose(); }
127+
});
128+
129+
KeyListener keys = new KeyListener() {
130+
@Override public void keyTyped(KeyEvent e) { System.out.println(e); }
131+
@Override public void keyPressed(KeyEvent e) { System.out.println(e); }
132+
@Override public void keyReleased(KeyEvent e) { System.out.println(e); }
133+
};
134+
MouseListener mouse = new MouseListener() {
135+
@Override public void mouseClicked(MouseEvent e) { System.out.println(e); }
136+
@Override public void mousePressed(MouseEvent e) { System.out.println(e); }
137+
@Override public void mouseReleased(MouseEvent e) { System.out.println(e); }
138+
@Override public void mouseEntered(MouseEvent e) { System.out.println(e); }
139+
@Override public void mouseExited(MouseEvent e) { System.out.println(e); }
140+
};
141+
MouseMotionListener mouseMotion = new MouseMotionListener() {
142+
@Override public void mouseDragged(MouseEvent e) { System.out.println(e); }
143+
@Override public void mouseMoved(MouseEvent e) { System.out.println(e); }
144+
};
145+
MouseWheelListener mouseWheel = System.out::println;
146+
147+
f.addKeyListener(keys);
148+
f.addMouseListener(mouse);
149+
f.addMouseMotionListener(mouseMotion);
150+
f.addMouseWheelListener(mouseWheel);
151+
152+
p.addKeyListener(keys);
153+
p.addMouseListener(mouse);
154+
p.addMouseMotionListener(mouseMotion);
155+
p.addMouseWheelListener(mouseWheel);
156+
157+
f.setBounds(200, 200, 400, 400);
158+
f.setVisible(true);
159+
});
160+
}
161+
}

0 commit comments

Comments
 (0)