JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
TestSwingAWTRobotUsageBeforeJOGLInitBug411.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.jogl.newt;
30
31import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
32import com.jogamp.opengl.test.junit.util.*;
33
34import java.lang.reflect.InvocationTargetException;
35
36import com.jogamp.nativewindow.NativeWindowFactory;
37import com.jogamp.nativewindow.util.RectangleImmutable;
38import com.jogamp.opengl.GLAutoDrawable;
39import com.jogamp.opengl.GLProfile;
40import com.jogamp.opengl.GLCapabilities;
41import com.jogamp.opengl.awt.GLCanvas;
42
43import com.jogamp.opengl.util.Animator;
44import com.jogamp.newt.Screen;
45import com.jogamp.newt.opengl.GLWindow;
46import com.jogamp.newt.awt.NewtCanvasAWT;
47
48import java.awt.BorderLayout;
49import java.awt.Canvas;
50import java.awt.Color;
51import java.awt.Dimension;
52import java.awt.AWTException;
53import java.awt.Robot;
54import java.awt.Point;
55import java.awt.event.InputEvent;
56import java.awt.event.MouseAdapter;
57import java.awt.event.MouseEvent;
58import java.awt.event.WindowAdapter;
59import java.awt.event.WindowEvent;
60
61import com.jogamp.opengl.GLEventListener;
62import javax.swing.JButton;
63import javax.swing.JFrame;
64import javax.swing.JPanel;
65import javax.swing.BorderFactory;
66import javax.swing.border.Border;
67
68import org.junit.Assert;
69import org.junit.BeforeClass;
70import org.junit.AfterClass;
71import org.junit.Test;
72import org.junit.FixMethodOrder;
73import org.junit.runners.MethodSorters;
74
75@FixMethodOrder(MethodSorters.NAME_ASCENDING)
77 static long durationPerTest = 150; // ms
78 static Robot robot;
79 static Border border;
80 static JFrame frame;
81 static JButton button;
82 static JPanel panel;
83 static JPanel colorPanel;
84 static boolean windowClosing;
85
86 boolean modLightBrighter = true;
87
88 Color modLight(final Color c) {
89 Color c2;
90 if(modLightBrighter) {
91 c2 = c.brighter();
92 } else {
93 c2 = c.darker();
94 }
95 if(c2.equals(c)) {
96 modLightBrighter = !modLightBrighter;
97 }
98 return c2;
99 }
100
101 class SwingGLAction implements GLEventListener {
102 public void init(final GLAutoDrawable glad) {
103 }
104
105 public void dispose(final GLAutoDrawable glad) {
106 }
107
108 public void display(final GLAutoDrawable glad) {
109 colorPanel.setBackground(modLight(colorPanel.getBackground()));
110 colorPanel.repaint();
111 }
112
113 public void reshape(final GLAutoDrawable glad, final int x, final int y, final int width, final int height) {
114 }
115 }
116
117 @BeforeClass
118 public static void setup() throws InterruptedException, InvocationTargetException, AWTException {
119 System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.setup(): Start Pre-JOGL-Swing");
120
121 // simulate AWT usage before JOGL's initialization of X11 threading
122 windowClosing=false;
123 border = BorderFactory.createLineBorder (Color.yellow, 2);
124
125 panel = new JPanel();
126 panel.setLayout(new BorderLayout());
127
128 button = new JButton("Click me");
129 button.addMouseListener(new MouseAdapter() {
130 public void mouseClicked(final MouseEvent e) {
131 System.err.println("Test: "+e);
132 }
133 });
134 panel.add(button, BorderLayout.NORTH);
135
136 colorPanel = new JPanel();
137 final Dimension size = new Dimension(400,100);
138 colorPanel.setPreferredSize(size);
139 colorPanel.setBorder(border);
140 panel.add(colorPanel, BorderLayout.SOUTH);
141
142 frame = new JFrame("PRE JOGL");
143 frame.addWindowListener( new WindowAdapter() {
144 public void windowClosing(final WindowEvent ev) {
145 windowClosing=true;
146 }
147 });
148 frame.setContentPane(panel);
149
150 // AWT/Swing: From here on (post setVisible(true)
151 // you need to use AWT/Swing's invokeAndWait()
152
153 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
154 public void run() {
155 frame.setSize(512, 512);
156 frame.setLocation(0, 0);
157 frame.pack();
158 frame.setVisible(true);
159 colorPanel.setBackground(Color.white);
160 colorPanel.repaint();
161 }});
162
163 robot = new Robot();
164 robot.setAutoWaitForIdle(true);
165
166 // NativeWindow/JOGL is not initialized yet ..
167 for (int wait=0; wait<TestUtil.POLL_DIVIDER && !frame.isVisible(); wait++) {
168 Thread.sleep(TestUtil.TIME_SLICE);
169 }
170 Assert.assertEquals(true, frame.isVisible());
171
172 System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.setup(): Before NativeWindow init");
173
175
178 AWTRobotUtil.requestFocus(robot, button);
179
180 System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.setup(): Before JOGL init");
181
182 // just to trigger JOGL initialization at a well defined point ..
184
185 System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.setup(): End Pre-JOGL-Swing");
186 }
187
188 @AfterClass
189 public static void release() throws InterruptedException, InvocationTargetException {
190 System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.release(): Start");
191 robot = null;
192 Assert.assertNotNull(frame);
193 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
194 public void run() {
195 frame.dispose();
196 }
197 });
198 frame=null;
199 System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.release(): End");
200 }
201
202 protected void runTestGL(final Canvas canvas, final GLAutoDrawable drawable)
203 throws AWTException, InterruptedException, InvocationTargetException {
204
205 final Dimension size = new Dimension(400,400);
206 canvas.setPreferredSize(size);
207
208 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
209 public void run() {
210 panel.add(canvas, BorderLayout.CENTER);
211 frame.pack();
212 }
213 });
214
216
217 Assert.assertEquals(true, GLTestUtil.waitForRealized(drawable, true, null));
218
219 drawable.addGLEventListener(new GearsES2());
220
221 for(int i=0; i<100; i++) {
222 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
223 public void run() {
224 colorPanel.setBackground(modLight(colorPanel.getBackground()));
225 colorPanel.repaint();
226 }
227 });
228 drawable.display(); // one in process display
229 Thread.sleep(10);
230 }
231
232 colorPanel.setBackground(Color.blue);
233 drawable.addGLEventListener(new SwingGLAction());
234
235 final Point p0 = canvas.getLocationOnScreen();
236 p0.translate(10,10);
237 robot.mouseMove( (int) ( p0.getX() + .5 ) ,
238 (int) ( p0.getY() + .5 ) );
239 robot.mousePress(InputEvent.BUTTON1_MASK);
240 for(int i=0; !windowClosing && i<durationPerTest/10; i++) {
241 p0.translate(1,1);
242 robot.mouseMove( (int) ( p0.getX() + .5 ) ,
243 (int) ( p0.getY() + .5 ) );
244 Thread.sleep(10);
245 }
246 robot.mouseRelease(InputEvent.BUTTON1_MASK);
247
248 for(int i=0; !windowClosing && i<durationPerTest/100; i++) {
249 Thread.sleep(100);
250 }
251
252 Assert.assertNotNull(canvas);
253 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
254 public void run() {
255 panel.remove(canvas);
256 frame.pack();
257 }
258 });
259 }
260
261 @Test
262 public void test01NewtCanvasAWT() throws AWTException, InterruptedException, InvocationTargetException {
263 System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.test01NewtCanvasAWT(): Start");
264
265 final GLProfile glp = GLProfile.getGL2ES2();
266 final GLCapabilities caps = new GLCapabilities(glp);
267
268 final GLWindow win0 = GLWindow.create(caps);
269 win0.setSize(100,100);
270 win0.setVisible(true);
271 Assert.assertEquals(true, NewtTestUtil.waitForRealized(win0, true, null));
272
273 final Screen screen = win0.getScreen();
274 final RectangleImmutable screenBoundsInWinU = screen.getViewportInWindowUnits();
275 win0.setPosition(screenBoundsInWinU.getX()-150, 0);
276 win0.addGLEventListener(new GearsES2());
277 final Animator anim = new Animator(win0);
278 anim.start();
279
280 final GLWindow win1 = GLWindow.create(caps);
281 final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(win1);
282 anim.add(win1);
283 runTestGL(newtCanvasAWT, win1);
284
285 win0.destroy();
286 Assert.assertEquals(true, NewtTestUtil.waitForRealized(win0, false, null));
287 Assert.assertEquals(false, win0.isNativeValid());
288 Assert.assertEquals(true, anim.isAnimating()); // due to newtCanvasAWT/win1
289
290 newtCanvasAWT.destroy(); // destroys both newtCanvasAWT/win1
291 Assert.assertEquals(false, win1.isNativeValid());
292 Assert.assertEquals(false, win0.isNativeValid());
293 Assert.assertEquals(true, anim.isAnimating());
294
295 Assert.assertEquals(true, anim.stop());
296 Assert.assertEquals(false, anim.isAnimating());
297
298 System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.test01NewtCanvasAWT(): End");
299 }
300
301 @Test
302 public void test02GLCanvas() throws AWTException, InterruptedException, InvocationTargetException {
303 System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.test02GLCanvas(): Start");
304 final GLProfile glp = GLProfile.getGL2ES2();
305 final GLCapabilities caps = new GLCapabilities(glp);
306
307 final Animator anim = new Animator();
308 anim.start();
309
310 /**
311 * Using GLCanvas _and_ NEWT side by side currently causes a deadlock
312 * in AWT with AMD drivers !
313 *
314 GLWindow win0 = GLWindow.create(caps);
315 win0.setSize(100,100);
316 win0.setVisible(true);
317 Screen screen = win0.getScreen();
318 win0.setPosition(screen.getWidth()-150, 0);
319 win0.addGLEventListener(new Gears());
320 anim.add(win0);
321 */
322
323 final GLCanvas glCanvas = new GLCanvas(caps);
324 anim.add(glCanvas);
325 runTestGL(glCanvas, glCanvas);
326
327 anim.remove(glCanvas);
328 Assert.assertEquals(false, anim.isAnimating());
329
330 /**
331 win0.destroy();
332 Assert.assertEquals(true, anim.isAnimating());
333 */
334 Assert.assertEquals(true, anim.stop());
335 System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.test02GLCanvas(): End");
336 }
337
338 static int atoi(final String a) {
339 int i=0;
340 try {
341 i = Integer.parseInt(a);
342 } catch (final Exception ex) { ex.printStackTrace(); }
343 return i;
344 }
345
346 public static void main(final String args[]) {
347 for(int i=0; i<args.length; i++) {
348 if(args[i].equals("-time")) {
349 durationPerTest = atoi(args[++i]);
350 }
351 }
352 System.out.println("durationPerTest: "+durationPerTest);
353 org.junit.runner.JUnitCore.main(TestSwingAWTRobotUsageBeforeJOGLInitBug411.class.getName());
354 }
355}
Provides a pluggable mechanism for arbitrary window toolkits to adapt their components to the NativeW...
static synchronized void initSingleton()
Static one time initialization of this factory.
A screen may span multiple MonitorDevices representing their combined virtual size.
Definition: Screen.java:58
abstract RectangleImmutable getViewportInWindowUnits()
See Coordinate System.
AWT Canvas containing a NEWT Window using native parenting.
final void destroy()
Destroys this resource:
Pointer event of type PointerType.
Definition: MouseEvent.java:74
NEWT Window events are provided for notification purposes ONLY.
An implementation of GLAutoDrawable and Window interface, using a delegated Window instance,...
Definition: GLWindow.java:121
final void setPosition(final int x, final int y)
Sets the location of the window's client area excluding insets (window decorations) in window units.
Definition: GLWindow.java:525
final void setSize(final int width, final int height)
Sets the size of the window's client area in window units, excluding decorations.
Definition: GLWindow.java:625
final void setVisible(final boolean visible)
Calls setVisible(true, visible), i.e.
Definition: GLWindow.java:615
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.
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
static GLProfile getGL2ES2(final AbstractGraphicsDevice device)
Returns the GL2ES2 profile implementation, hence compatible w/ GL2ES2.
Definition: GLProfile.java:913
static void initSingleton()
Static initialization of JOGL.
Definition: GLProfile.java:204
A heavyweight AWT component which provides OpenGL rendering support.
Definition: GLCanvas.java:170
static void requestFocus(final Robot robot, final Object obj)
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 waitForRealized(final GLAutoDrawable glad, final boolean realized, final Runnable waitAction)
Definition: GLTestUtil.java:91
static boolean waitForRealized(final Screen screen, final boolean realized, final Runnable waitAction)
final synchronized void add(final GLAutoDrawable drawable)
Adds a drawable to this animator's list of rendering drawables.
final synchronized void remove(final GLAutoDrawable drawable)
Removes a drawable from the animator's list of rendering drawables.
final synchronized boolean start()
Starts this animator, if not running.
Definition: Animator.java:344
final synchronized boolean stop()
Stops this animator.
Definition: Animator.java:368
Immutable Rectangle interface, with its position on the top-left.
int getX()
x-position, left of rectangle.
A higher-level abstraction than GLDrawable which supplies an event based mechanism (GLEventListener) ...
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.