JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
TestParentingFocus01SwingAWTRobot.java
Go to the documentation of this file.
1/**
2 * Copyright 2010 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.opengl.test.junit.newt.event;
30
31import org.junit.Assert;
32import org.junit.AfterClass;
33import org.junit.Assume;
34
35import java.awt.AWTException;
36import java.awt.BorderLayout;
37import java.awt.Button;
38import java.awt.Container;
39import java.awt.Robot;
40import java.lang.reflect.InvocationTargetException;
41
42import com.jogamp.opengl.GLCapabilities;
43import com.jogamp.opengl.GLEventListener;
44import javax.swing.JFrame;
45
46import java.util.ArrayList;
47import java.io.IOException;
48
49import org.junit.BeforeClass;
50import org.junit.Test;
51import org.junit.FixMethodOrder;
52import org.junit.runners.MethodSorters;
53
54import com.jogamp.newt.awt.NewtCanvasAWT;
55import com.jogamp.newt.opengl.GLWindow;
56import com.jogamp.opengl.util.Animator;
57import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
58import com.jogamp.opengl.test.junit.newt.TestListenerCom01AWT;
59import com.jogamp.opengl.test.junit.util.*;
60
61/**
62 * Testing focus <i>mouse-click</i> and <i>programmatic</i> traversal of an AWT component tree with {@link NewtCanvasAWT} attached.
63 * <p>
64 * {@link JFrame} . {@link Container}+ [ Button*, {@link NewtCanvasAWT} . {@link GLWindow} ]
65 * </p>
66 * <p>
67 * <i>+ Container is the JFrame's implicit root content pane</i><br/>
68 * </p>
69 */
70@FixMethodOrder(MethodSorters.NAME_ASCENDING)
72 static int width, height;
73 static long durationPerTest = 10;
74 static long awtWaitTimeout = 1000;
75
76 static GLCapabilities glCaps;
77
78 @BeforeClass
79 public static void initClass() {
80 width = 640;
81 height = 480;
82 glCaps = new GLCapabilities(null);
83 }
84
85 @AfterClass
86 public static void release() {
87 }
88
89 @Test
90 public void testFocus01ProgrFocus() throws AWTException, InterruptedException, InvocationTargetException {
91 testFocus01ProgrFocusImpl(null);
92 }
93
94 @Test
95 public void testFocus02RobotFocus() throws AWTException, InterruptedException, InvocationTargetException {
96 final Robot robot = new Robot();
97 robot.setAutoWaitForIdle(true);
98 testFocus01ProgrFocusImpl(robot);
99 }
100
101 private void testFocus01ProgrFocusImpl(final Robot robot) throws AWTException,
102 InvocationTargetException, InterruptedException {
103 final ArrayList<EventCountAdapter> eventCountAdapters = new ArrayList<EventCountAdapter>();
104
105 // Create a window.
106 final GLWindow glWindow1 = GLWindow.create(glCaps);
107 glWindow1.setTitle("testNewtChildFocus");
108 final GLEventListener demo1 = new RedSquareES2();
109 TestListenerCom01AWT.setDemoFields(demo1, glWindow1, false);
110 glWindow1.addGLEventListener(demo1);
111 final NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1");
112 glWindow1.addWindowListener(glWindow1FA);
113
114 // Monitor NEWT focus and keyboard events.
115 final NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
116 eventCountAdapters.add(glWindow1KA);
117 glWindow1.addKeyListener(glWindow1KA);
118
119 // Wrap the window in a canvas.
120 final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1);
121 // newtCanvasAWT.setShallUseOffscreenLayer(true);
122
123 // Monitor AWT focus and keyboard events.
124 final AWTKeyAdapter newtCanvasAWTKA = new AWTKeyAdapter("NewtCanvasAWT");
125 newtCanvasAWT.addKeyListener(newtCanvasAWTKA);
126 eventCountAdapters.add(newtCanvasAWTKA);
127 final AWTFocusAdapter newtCanvasAWTFA = new AWTFocusAdapter("NewtCanvasAWT");
128 newtCanvasAWT.addFocusListener(newtCanvasAWTFA);
129
130 // Add the canvas to a frame, and make it all visible.
131 final JFrame frame1 = new JFrame("Swing AWT Parent Frame: "
132 + glWindow1.getTitle());
133 frame1.getContentPane().add(newtCanvasAWT, BorderLayout.CENTER);
134 final Button button = new Button("Click me ..");
135 final AWTFocusAdapter buttonFA = new AWTFocusAdapter("Button");
136 button.addFocusListener(buttonFA);
137 final AWTKeyAdapter buttonKA = new AWTKeyAdapter("Button");
138 button.addKeyListener(buttonKA);
139 eventCountAdapters.add(buttonKA);
140 final AWTMouseAdapter buttonMA = new AWTMouseAdapter("Button");
141 button.addMouseListener(buttonMA);
142 eventCountAdapters.add(buttonMA);
143
144 frame1.getContentPane().add(button, BorderLayout.NORTH);
145 frame1.setSize(width, height);
146 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
147 public void run() {
148 frame1.setVisible(true);
149 } } );
150 Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame1, true, null));
151 Assert.assertEquals(true, NewtTestUtil.waitForRealized(glWindow1, true, null));
153 Assert.assertTrue(AWTRobotUtil.toFrontAndRequestFocus(robot, frame1));
154
155 Thread.sleep(durationPerTest); // manual testing
156
157 int wait=0;
158 while(wait<awtWaitTimeout/100 && glWindow1.getTotalFPSFrames()<1) { Thread.sleep(awtWaitTimeout/10); wait++; }
159 System.err.println("Frames for initial setVisible(true): "+glWindow1.getTotalFPSFrames());
160 Assert.assertTrue(glWindow1.isVisible());
161 Assert.assertTrue(0 < glWindow1.getTotalFPSFrames());
162
163 // Continuous animation ..
164 final Animator animator = new Animator(glWindow1);
165 animator.start();
166
167 // Button Focus
168 Thread.sleep(200); // allow event sync
169
170 System.err.println("FOCUS AWT Button request");
171 EventCountAdapterUtil.reset(eventCountAdapters);
172 AWTRobotUtil.assertRequestFocusAndWait(robot, button, button, buttonFA, null); // OSX sporadically button did not gain - major UI failure
173 Assert.assertEquals(false, glWindow1FA.focusGained());
174 Assert.assertEquals(false, newtCanvasAWTFA.focusGained());
175 System.err.println("FOCUS AWT Button sync");
176 AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, button, buttonKA);
177 AWTRobotUtil.assertMouseClick(robot, java.awt.event.InputEvent.BUTTON1_MASK, 1,
178 button, buttonMA);
179 AWTRobotUtil.assertMouseClick(robot, java.awt.event.InputEvent.BUTTON1_MASK, 2,
180 button, buttonMA);
181
182 // Request the AWT focus, which should automatically provide the NEWT window with focus.
183 Thread.sleep(100); // allow event sync
184 System.err.println("FOCUS NEWT Canvas/GLWindow request");
185 EventCountAdapterUtil.reset(eventCountAdapters);
186 AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonFA); // OSX sporadically button did not loose - minor UI failure
187 // Manually tested on Java7/[Linux,Windows] (where this assertion failed),
188 // Should be OK to have the AWT component assume it also has the focus.
189 // Assert.assertTrue("Focus prev. gained, but NewtCanvasAWT didn't loose it. Gainer: "+glWindow1FA+"; Looser "+newtCanvasAWTFA,
190 // AWTRobotUtil.waitForFocus(glWindow1FA, newtCanvasAWTFA));
191 if( !TestUtil.waitForFocus(glWindow1FA, newtCanvasAWTFA, null) ) {
192 System.err.println("Info: Focus prev. gained, but NewtCanvasAWT didn't loose it. Gainer: "+glWindow1FA+"; Looser "+newtCanvasAWTFA);
193 }
194 System.err.println("FOCUS NEWT Canvas/GLWindow sync");
195 AWTRobotUtil.assertKeyType(robot, java.awt.event.KeyEvent.VK_A, 2, glWindow1, glWindow1KA);
196 Assert.assertEquals("AWT parent canvas received non consumed keyboard events", newtCanvasAWTKA.getConsumedCount(), newtCanvasAWTKA.getCount());
197 if( !newtCanvasAWT.isAWTEventPassThrough() ) {
198 Assert.assertEquals("AWT parent canvas received consumed keyboard events", 0, newtCanvasAWTKA.getConsumedCount());
199 }
200
201 // Remove listeners to avoid logging during dispose/destroy.
202 glWindow1.removeKeyListener(glWindow1KA);
203 glWindow1.removeWindowListener(glWindow1FA);
204 newtCanvasAWT.removeKeyListener(newtCanvasAWTKA);
205 newtCanvasAWT.removeFocusListener(newtCanvasAWTFA);
206
207 // Shutdown the test.
208 animator.stop();
209 try {
210 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
211 public void run() {
212 frame1.setVisible(false);
213 frame1.dispose();
214 }});
215 } catch( final Throwable throwable ) {
216 throwable.printStackTrace();
217 Assume.assumeNoException( throwable );
218 }
219 glWindow1.destroy();
220 Assert.assertEquals(true, NewtTestUtil.waitForRealized(glWindow1, false, null));
221 }
222
223 static int atoi(final String a) {
224 int i=0;
225 try {
226 i = Integer.parseInt(a);
227 } catch (final Exception ex) { ex.printStackTrace(); }
228 return i;
229 }
230
231 public static void main(final String args[]) throws IOException {
232 for(int i=0; i<args.length; i++) {
233 if(args[i].equals("-time")) {
234 durationPerTest = atoi(args[++i]);
235 }
236 }
237 /**
238 BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
239 System.err.println("Press enter to continue");
240 System.err.println(stdin.readLine());
241 */
242 System.out.println("durationPerTest: "+durationPerTest);
243 final String tstname = TestParentingFocus01SwingAWTRobot.class.getName();
244 org.junit.runner.JUnitCore.main(tstname);
245 }
246
247
248}
AWT Canvas containing a NEWT Window using native parenting.
final boolean isAWTEventPassThrough()
Returns true if Key and Mouse input events will be passed through AWT, otherwise only the NEWT child ...
An implementation of GLAutoDrawable and Window interface, using a delegated Window instance,...
Definition: GLWindow.java:121
final void setTitle(final String title)
Definition: GLWindow.java:297
final void addKeyListener(final KeyListener l)
Appends the given com.jogamp.newt.event.KeyListener to the end of the list.
Definition: GLWindow.java:902
final void removeWindowListener(final WindowListener l)
Definition: GLWindow.java:877
final void addWindowListener(final WindowListener l)
Appends the given com.jogamp.newt.event.WindowListener to the end of the list.
Definition: GLWindow.java:882
final void removeKeyListener(final KeyListener l)
Definition: GLWindow.java:912
final void destroy()
Destroys all resources associated with this GLAutoDrawable, inclusive the GLContext.
Definition: GLWindow.java:605
static GLWindow create(final GLCapabilitiesImmutable caps)
Creates a new GLWindow attaching a new Window referencing a new default Screen and default Display wi...
Definition: GLWindow.java:169
Specifies a set of OpenGL capabilities.
static void setDemoFields(final GLEventListener demo, final GLWindow glWindow, final boolean debug)
Testing focus mouse-click and programmatic traversal of an AWT component tree with NewtCanvasAWT atta...
static void assertKeyType(Robot robot, final int keyCode, final int typeCount, final Object obj, final KeyEventCountAdapter counter)
FIXME: AWTRobotUtil Cleanup: Use specific type for argument object.
static void assertMouseClick(Robot robot, final int mouseButton, final int clickCount, final Object obj, final InputEventCountAdapter counter)
FIXME: AWTRobotUtil Cleanup: Use specific type for argument object.
static boolean toFrontAndRequestFocus(Robot robot, final java.awt.Window window)
toFront, call setVisible(true) and toFront(), after positioning the mouse in the middle of the window...
static boolean waitForVisible(final java.awt.Component comp, final boolean visible, final Runnable waitAction)
static void assertRequestFocusAndWait(final Robot robot, final Object requestFocus, final Object waitForFocus, final FocusEventCountAdapter gain, final FocusEventCountAdapter lost)
static void reset(final EventCountAdapter[] adapters)
static boolean waitForRealized(final Screen screen, final boolean realized, final Runnable waitAction)
static boolean waitForFocus(final FocusEventCountAdapter gain, final FocusEventCountAdapter lost, final Runnable waitAction)
Definition: TestUtil.java:50
void addGLEventListener(GLEventListener listener)
Adds the given listener to the end of this drawable queue.
Declares events which client code can use to manage OpenGL rendering into a GLAutoDrawable.