JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
TestParenting01cSwingAWT.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.parenting;
30
31import java.lang.reflect.*;
32
33import org.junit.Assert;
34import org.junit.BeforeClass;
35import org.junit.Test;
36import org.junit.FixMethodOrder;
37import org.junit.runners.MethodSorters;
38
39import java.awt.Button;
40import java.awt.BorderLayout;
41import java.awt.Container;
42
43import javax.swing.JFrame;
44import javax.swing.JPanel;
45import javax.swing.SwingUtilities;
46import javax.swing.WindowConstants;
47import com.jogamp.opengl.*;
48
49import com.jogamp.opengl.util.Animator;
50import com.jogamp.common.util.InterruptSource;
51import com.jogamp.newt.*;
52import com.jogamp.newt.opengl.*;
53import com.jogamp.newt.awt.NewtCanvasAWT;
54
55import java.io.IOException;
56
57import com.jogamp.opengl.test.junit.util.*;
58import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
59
60@FixMethodOrder(MethodSorters.NAME_ASCENDING)
62 static int width, height;
63 static long durationPerTest = 800;
64 static long waitReparent = 0;
65 static GLCapabilities glCaps;
66
67 @BeforeClass
68 public static void initClass() {
69 width = 640;
70 height = 480;
71 glCaps = new GLCapabilities(null);
72 }
73
74 static class GLDisturbanceAction implements Runnable {
75 public boolean isRunning = false;
76 private volatile boolean shallStop = false;
77 private final GLAutoDrawable glad;
78 private final GLRunnable glRunnable;
79
80 public GLDisturbanceAction(final GLAutoDrawable glad) {
81 this.glad = glad;
82 this.glRunnable = new GLRunnableDummy();
83 }
84
85 public void waitUntilRunning() {
86 synchronized(this) {
87 while(!isRunning) {
88 try {
89 this.wait();
90 } catch (final InterruptedException e) { e.printStackTrace(); }
91 }
92 }
93 }
94
95 public void stopAndWaitUntilDone() {
96 shallStop = true;
97 synchronized(this) {
98 while(isRunning) {
99 try {
100 this.wait();
101 } catch (final InterruptedException e) { e.printStackTrace(); }
102 }
103 }
104 }
105
106 public void run() {
107 synchronized(this) {
108 isRunning = true;
109 this.notifyAll();
110 System.err.println("$");
111 }
112 while(!shallStop) {
113 try {
114 glad.invoke(true, glRunnable);
115 Thread.sleep(100);
116 } catch (final Throwable t) {}
117 }
118 synchronized(this) {
119 isRunning = false;
120 this.notifyAll();
121 }
122 }
123 }
124
125 @Test
126 public void test01CreateVisibleDestroy1() throws InterruptedException, InvocationTargetException {
127 /**
128 * JFrame . JPanel . Container . NewtCanvasAWT . GLWindow
129 */
130 final GLWindow glWindow1 = GLWindow.create(glCaps);
131 Assert.assertNotNull(glWindow1);
132 Assert.assertEquals(false, glWindow1.isVisible());
133 Assert.assertEquals(false, glWindow1.isNativeValid());
134 Assert.assertNull(glWindow1.getParent());
135 glWindow1.setTitle("testWindowParenting01CreateVisibleDestroy");
136 final GLEventListener demo1 = new RedSquareES2();
137 setDemoFields(demo1, glWindow1, false);
138 glWindow1.addGLEventListener(demo1);
139 final Animator animator1 = new Animator(glWindow1);
140 animator1.setUpdateFPSFrames(1, null);
141 animator1.start();
142
143 final GLDisturbanceAction disturbanceAction = new GLDisturbanceAction(glWindow1);
144 new InterruptSource.Thread(null, disturbanceAction).start();
145 disturbanceAction.waitUntilRunning();
146
147 final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1);
148 Assert.assertNotNull(newtCanvasAWT);
149 Assert.assertEquals(false, glWindow1.isVisible());
150 Assert.assertEquals(false, glWindow1.isNativeValid());
151 Assert.assertNull(glWindow1.getParent());
152
153 final Container container1 = new Container();
154 container1.setLayout(new BorderLayout());
155 container1.add(new Button("north"), BorderLayout.NORTH);
156 container1.add(new Button("south"), BorderLayout.SOUTH);
157 container1.add(new Button("east"), BorderLayout.EAST);
158 container1.add(new Button("west"), BorderLayout.WEST);
159 container1.add(newtCanvasAWT, BorderLayout.CENTER);
160
161 final JPanel jPanel1 = new JPanel();
162 jPanel1.setLayout(new BorderLayout());
163 jPanel1.add(new Button("north"), BorderLayout.NORTH);
164 jPanel1.add(new Button("south"), BorderLayout.SOUTH);
165 jPanel1.add(new Button("east"), BorderLayout.EAST);
166 jPanel1.add(new Button("west"), BorderLayout.WEST);
167 jPanel1.add(container1, BorderLayout.CENTER);
168
169 final JFrame jFrame1 = new JFrame("Swing Parent JFrame");
170 // jFrame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
171 jFrame1.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); // equivalent to Frame, use windowClosing event!
172 jFrame1.setContentPane(jPanel1);
173 System.err.println("Demos: 1 - Visible");
174 SwingUtilities.invokeAndWait(new Runnable() {
175 public void run() {
176 jFrame1.setSize(width, height);
177 jFrame1.validate();
178 jFrame1.setVisible(true);
179 }
180 });
181 Assert.assertEquals(true, NewtTestUtil.waitForRealized(glWindow1, true, null));
182 Assert.assertEquals(true, NewtTestUtil.waitForVisible(glWindow1, true, null));
183
184 // visible test
185 Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParent());
186
187 while(animator1.isAnimating() && animator1.getTotalFPSDuration()<durationPerTest) {
188 Thread.sleep(100);
189 }
190 System.err.println("Demos: 2 - StopAnimator");
191 animator1.stop();
192 Assert.assertEquals(false, animator1.isAnimating());
193
194 SwingUtilities.invokeAndWait(new Runnable() {
195 public void run() {
196 System.err.println("Demos: 3 - !Visible");
197 jFrame1.setVisible(false);
198 } });
199 Assert.assertEquals(true, NewtTestUtil.waitForVisible(glWindow1, false, null));
200
201 SwingUtilities.invokeAndWait(new Runnable() {
202 public void run() {
203 System.err.println("Demos: 4 - Visible");
204 jFrame1.setVisible(true);
205 } });
206 Assert.assertEquals(true, NewtTestUtil.waitForVisible(glWindow1, true, null));
207
208 final boolean wasOnscreen = glWindow1.getChosenCapabilities().isOnscreen();
209
210 // Always recommended to remove our native parented Window
211 // from the AWT resources before destruction, since it could lead
212 // to a BadMatch X11 error w/o.
213 SwingUtilities.invokeAndWait(new Runnable() {
214 public void run() {
215 System.err.println("Demos: 5 - X Container");
216 jPanel1.remove(container1);
217 jFrame1.validate();
218 } });
219 if( wasOnscreen ) {
220 Assert.assertEquals(true, glWindow1.isNativeValid());
221 } // else OK to be destroyed - due to offscreen/onscreen transition
222
223 SwingUtilities.invokeAndWait(new Runnable() {
224 public void run() {
225 System.err.println("Demos: 6 - X Frame");
226 jFrame1.dispose();
227 } });
228 if( wasOnscreen ) {
229 Assert.assertEquals(true, glWindow1.isNativeValid());
230 } // else OK to be destroyed - due to offscreen/onscreen transition
231
232 System.err.println("Demos: 7 - X GLWindow");
233 glWindow1.destroy();
234 Assert.assertEquals(false, glWindow1.isNativeValid());
235
236 System.err.println("Demos: 8 - X DisturbanceThread");
237 disturbanceAction.stopAndWaitUntilDone();
238 }
239
240 @Test
241 public void test02AWTWinHopFrame2Frame() throws InterruptedException, InvocationTargetException {
242 /**
243 * JFrame . JPanel . Container . NewtCanvasAWT . GLWindow
244 */
245 final GLWindow glWindow1 = GLWindow.create(glCaps);
246 Assert.assertNotNull(glWindow1);
247 Assert.assertEquals(false, glWindow1.isVisible());
248 Assert.assertEquals(false, glWindow1.isNativeValid());
249 Assert.assertNull(glWindow1.getParent());
250 glWindow1.setTitle("testWindowParenting01CreateVisibleDestroy");
251 final GLEventListener demo1 = new RedSquareES2();
252 setDemoFields(demo1, glWindow1, false);
253 /*
254 glWindow1.addGLEventListener(new GLEventListener() {
255 @Override
256 public void init(GLAutoDrawable drawable) {
257 System.err.println("XXX init");
258 }
259 @Override
260 public void dispose(GLAutoDrawable drawable) {
261 System.err.println("XXX dispose");
262 // Thread.dumpStack();
263 }
264 @Override
265 public void display(GLAutoDrawable drawable) {}
266 @Override
267 public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
268 System.err.println("XXX reshape");
269 // Thread.dumpStack();
270 }
271 }); */
272 glWindow1.addGLEventListener(demo1);
273 final Animator animator1 = new Animator(glWindow1);
274 animator1.setUpdateFPSFrames(1, null);
275 animator1.start();
276
277 final GLDisturbanceAction disturbanceAction = new GLDisturbanceAction(glWindow1);
278 new InterruptSource.Thread(null, disturbanceAction).start();
279 disturbanceAction.waitUntilRunning();
280
281 final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1);
282 Assert.assertNotNull(newtCanvasAWT);
283 Assert.assertEquals(false, glWindow1.isVisible());
284 Assert.assertEquals(false, glWindow1.isNativeValid());
285 Assert.assertNull(glWindow1.getParent());
286
287 final Container container1 = new Container();
288 container1.setLayout(new BorderLayout());
289 container1.add(new Button("north"), BorderLayout.NORTH);
290 container1.add(new Button("south"), BorderLayout.SOUTH);
291 container1.add(new Button("east"), BorderLayout.EAST);
292 container1.add(new Button("west"), BorderLayout.WEST);
293 container1.add(newtCanvasAWT, BorderLayout.CENTER);
294
295 final JPanel jPanel1 = new JPanel();
296 jPanel1.setLayout(new BorderLayout());
297 jPanel1.add(new Button("north"), BorderLayout.NORTH);
298 jPanel1.add(new Button("south"), BorderLayout.SOUTH);
299 jPanel1.add(new Button("east"), BorderLayout.EAST);
300 jPanel1.add(new Button("west"), BorderLayout.WEST);
301 jPanel1.add(container1, BorderLayout.CENTER);
302
303 final JFrame jFrame1 = new JFrame("Swing Parent JFrame");
304 // jFrame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
305 jFrame1.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); // equivalent to Frame, use windowClosing event!
306 jFrame1.setContentPane(jPanel1);
307 SwingUtilities.invokeAndWait(new Runnable() {
308 public void run() {
309 jFrame1.setLocation(0, 0);
310 jFrame1.setSize(width, height);
311 jFrame1.setVisible(true);
312 }
313 });
314
315 final JPanel jPanel2 = new JPanel();
316 jPanel2.setLayout(new BorderLayout());
317 jPanel2.add(new Button("north"), BorderLayout.NORTH);
318 jPanel2.add(new Button("south"), BorderLayout.SOUTH);
319 jPanel2.add(new Button("east"), BorderLayout.EAST);
320 jPanel2.add(new Button("west"), BorderLayout.WEST);
321
322 final JFrame jFrame2 = new JFrame("Swing Parent JFrame");
323 // jFrame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
324 jFrame2.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); // equivalent to Frame, use windowClosing event!
325 jFrame2.setContentPane(jPanel2);
326 SwingUtilities.invokeAndWait(new Runnable() {
327 public void run() {
328 jFrame2.setLocation(640, 480);
329 jFrame2.setSize(width, height);
330 jFrame2.setVisible(true);
331 }
332 });
333
334 // visible test
335 Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParent());
336
337 final boolean wasOnscreen = glWindow1.getChosenCapabilities().isOnscreen();
338
339 int state = 0;
340 while(animator1.isAnimating() && animator1.getTotalFPSDuration()<3*durationPerTest) {
341 Thread.sleep(durationPerTest);
342 switch(state) {
343 case 0:
344 SwingUtilities.invokeAndWait(new Runnable() {
345 public void run() {
346 container1.remove(newtCanvasAWT);
347 jPanel2.add(newtCanvasAWT, BorderLayout.CENTER);
348 jFrame1.validate();
349 jFrame2.validate();
350 } });
351 break;
352 case 1:
353 SwingUtilities.invokeAndWait(new Runnable() {
354 public void run() {
355 jPanel2.remove(newtCanvasAWT);
356 container1.add(newtCanvasAWT, BorderLayout.CENTER);
357 jFrame1.validate();
358 jFrame2.validate();
359 } });
360 break;
361 }
362 state++;
363 }
364
365 animator1.stop();
366 Assert.assertEquals(false, animator1.isAnimating());
367
368 /*
369 * Always recommended to remove our native parented Window
370 * from the AWT resources before destruction, since it could lead
371 * to a BadMatch X11 error w/o (-> XAWT related).
372 * Or ensure old/new parent is visible, see below.
373 *
374 SwingUtilities.invokeAndWait(new Runnable() {
375 public void run() {
376 System.err.println("Demos: 1 - X Container 1");
377 container1.remove(newtCanvasAWT);
378 jFrame1.validate();
379 System.err.println("Demos: 1 - X Container 2");
380 jPanel2.remove(newtCanvasAWT);
381 jFrame2.validate();
382 } }); */
383 /*
384 * Invisible X11 windows may also case BadMatch (-> XAWT related)
385 */
386 SwingUtilities.invokeAndWait(new Runnable() {
387 public void run() {
388 System.err.println("Demos: 2 - !visible");
389 jFrame1.setVisible(false);
390 System.err.println("Demos: 3 - !visible");
391 jFrame2.setVisible(false);
392 } });
393 Assert.assertEquals(true, glWindow1.isNativeValid());
394
395 SwingUtilities.invokeAndWait(new Runnable() {
396 public void run() {
397 System.err.println("Demos: 4 - X frame");
398 jFrame1.dispose();
399 System.err.println("Demos: 5 - X frame");
400 jFrame2.dispose();
401 } });
402 if( wasOnscreen ) {
403 Assert.assertEquals(true, glWindow1.isNativeValid());
404 } // else OK to be destroyed - due to offscreen/onscreen transition
405
406 System.err.println("Demos: 6 - X GLWindow");
407 glWindow1.destroy();
408 Assert.assertEquals(false, glWindow1.isNativeValid());
409
410 System.err.println("Demos: 7 - X DisturbanceThread");
411 disturbanceAction.stopAndWaitUntilDone();
412 }
413
414 public static void setDemoFields(final GLEventListener demo, final GLWindow glWindow, final boolean debug) {
415 Assert.assertNotNull(demo);
416 Assert.assertNotNull(glWindow);
417 final Window window = glWindow.getDelegatedWindow();
418 if(debug) {
419 MiscUtils.setFieldIfExists(demo, "glDebug", true);
420 MiscUtils.setFieldIfExists(demo, "glTrace", true);
421 }
422 if(!MiscUtils.setFieldIfExists(demo, "window", window)) {
423 MiscUtils.setFieldIfExists(demo, "glWindow", glWindow);
424 }
425 }
426
427 static int atoi(final String a) {
428 int i=0;
429 try {
430 i = Integer.parseInt(a);
431 } catch (final Exception ex) { ex.printStackTrace(); }
432 return i;
433 }
434
435 public static void main(final String args[]) throws IOException {
436 for(int i=0; i<args.length; i++) {
437 if(args[i].equals("-time")) {
438 durationPerTest = atoi(args[++i]);
439 } else if(args[i].equals("-wait")) {
440 waitReparent = atoi(args[++i]);
441 }
442 }
443 System.err.println("durationPerTest "+durationPerTest);
444 System.err.println("waitReparent "+waitReparent);
445 org.junit.runner.JUnitCore.main(TestParenting01cSwingAWT.class.getName());
446 /**
447 String tstname = TestParenting01cSwingAWT.class.getName();
448 org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] {
449 tstname,
450 "filtertrace=true",
451 "haltOnError=false",
452 "haltOnFailure=false",
453 "showoutput=true",
454 "outputtoformatters=true",
455 "logfailedtests=true",
456 "logtestlistenerevents=true",
457 "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter",
458 "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } ); */
459 }
460
461}
AWT Canvas containing a NEWT Window using native parenting.
NativeWindow getNativeWindow()
Returns the associated NativeWindow of this NativeWindowHolder, which is identical to getNativeSurfac...
An implementation of GLAutoDrawable and Window interface, using a delegated Window instance,...
Definition: GLWindow.java:121
final NativeWindow getParent()
Definition: GLWindow.java:282
final void setTitle(final String title)
Definition: GLWindow.java:297
final CapabilitiesImmutable getChosenCapabilities()
Gets an immutable set of chosen capabilities.
Definition: GLWindow.java:266
final void destroy()
Destroys all resources associated with this GLAutoDrawable, inclusive the GLContext.
Definition: GLWindow.java:605
final Window getDelegatedWindow()
If the implementation uses delegation, return the delegated Window instance, otherwise return this in...
Definition: GLWindow.java:277
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)
static boolean setFieldIfExists(final Object instance, final String fieldName, final Object value)
Definition: MiscUtils.java:193
static boolean waitForRealized(final Screen screen, final boolean realized, final Runnable waitAction)
static boolean waitForVisible(final Window win, final boolean visible, final Runnable waitAction)
final void setUpdateFPSFrames(final int frames, final PrintStream out)
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
boolean isOnscreen()
Returns whether an on- or offscreen surface is requested, available or chosen.
Specifying NEWT's Window functionality:
Definition: Window.java:115
A higher-level abstraction than GLDrawable which supplies an event based mechanism (GLEventListener) ...
boolean invoke(boolean wait, GLRunnable glRunnable)
Enqueues a one-shot GLRunnable, which will be executed within the next display() call after all regis...
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.