JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
TestBug816GLCanvasFrameHoppingB849B889AWT.java
Go to the documentation of this file.
1/**
2 * Copyright 2013 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 */
28package com.jogamp.opengl.test.junit.jogl.awt;
29
30import java.awt.BorderLayout;
31import java.awt.event.ActionEvent;
32import java.awt.event.ActionListener;
33import java.lang.reflect.InvocationTargetException;
34
35import com.jogamp.opengl.GLCapabilities;
36import com.jogamp.opengl.GLProfile;
37import com.jogamp.opengl.awt.GLCanvas;
38import javax.swing.JButton;
39import javax.swing.JFrame;
40import javax.swing.JPanel;
41import javax.swing.SwingUtilities;
42
43import org.junit.Assert;
44import org.junit.FixMethodOrder;
45import org.junit.Test;
46import org.junit.runners.MethodSorters;
47
48import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
49import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
50import com.jogamp.opengl.test.junit.util.MiscUtils;
51import com.jogamp.opengl.test.junit.util.UITestCase;
52
53/**
54 * Moving GLCanvas between 2 AWT JFrame
55 * <p>
56 * Validates bugs:
57 * <ul>
58 * <li>Bug 816: OSX CALayer Positioning Bug</li>
59 * <li>Bug 729: OSX CALayer shall honor the Component's visibility state</li>
60 * <li>Bug 849: AWT GLAutoDrawables (JAWTWindow) shall honor it's parent visibility state</li>
61 * <li>Bug 878: JAWTWindow's HierarchyListener doesn't set component visible (again) on 'addNotify(..)' - GLCanvas in JtabbedPane disappear</li>
62 * <li>Bug 889: GLCanvas disappear when moves between two JFrame</li>
63 * </ul>
64 * </p>
65 */
66@FixMethodOrder(MethodSorters.NAME_ASCENDING)
68 static long durationPerTest = 500*4; // ms
69 static boolean manual = false;
70
71 @Test
72 public void test01AllVisible() throws InterruptedException, InvocationTargetException {
73 test(false);
74 }
75
76 @Test
77 public void test02VisibleWithCanvas() throws InterruptedException, InvocationTargetException {
78 test(true);
79 }
80
81 private void test(final boolean onlyVisibleWithCanvas) throws InterruptedException, InvocationTargetException {
82 final JFrame frame1 = new JFrame("Bug889 #1");
83 final JPanel panel1 = new javax.swing.JPanel();
84 panel1.setLayout(new BorderLayout());
85 panel1.setSize(new java.awt.Dimension(640, 480));
86 frame1.setContentPane(panel1);
87 frame1.setSize(640, 480);
88 frame1.setLocation(64, 64);
89
90 final JFrame frame2 = new JFrame("Bug889 #2");
91 final JPanel panel2 = new javax.swing.JPanel();
92 panel2.setLayout(new BorderLayout());
93 panel2.setSize(new java.awt.Dimension(640, 480));
94 frame2.setContentPane(panel2);
95 frame2.setSize(640, 480);
96 frame2.setLocation(800, 64);
97
98 final GLProfile profile = GLProfile.get(GLProfile.GL2ES2);
99 final GLCapabilities glCapabilities = new GLCapabilities(profile);
100 final GLCanvas glCanvas = new GLCanvas(glCapabilities);
101 glCanvas.setSize(new java.awt.Dimension(640, 480));
102 glCanvas.addGLEventListener(new GearsES2(1));
103 panel1.add(glCanvas, BorderLayout.CENTER);
104
105 final JButton bMoveP1toP2 = new JButton("Move to Panel2");
106 bMoveP1toP2.addActionListener(new ActionListener() {
107 @Override
108 public void actionPerformed(final java.awt.event.ActionEvent evt) {
109 System.err.println("XXXX Move P1 -> P2 - START");
110 dumpGLCanvasStats(glCanvas);
111 panel2.add(glCanvas, BorderLayout.CENTER);
112 if( onlyVisibleWithCanvas ) {
113 frame1.setVisible(false);
114 frame2.setVisible(true);
115 frame2.toFront();
116 } else {
117 frame1.validate();
118 frame2.validate();
119 }
120 dumpGLCanvasStats(glCanvas);
121 System.err.println("XXXX Move P1 -> P2 - END");
122 }
123 });
124 panel1.add(bMoveP1toP2, BorderLayout.NORTH);
125
126 final JButton bMoveP2toP1 = new JButton("Move to Panel1");
127 bMoveP2toP1.addActionListener(new ActionListener() {
128 @Override
129 public void actionPerformed(final ActionEvent e) {
130 System.err.println("XXXX Move P2 -> P1 - START");
131 dumpGLCanvasStats(glCanvas);
132 panel1.add(glCanvas, BorderLayout.CENTER);
133 if( onlyVisibleWithCanvas ) {
134 frame2.setVisible(false);
135 frame1.setVisible(true);
136 frame1.toFront();
137 } else {
138 frame2.validate();
139 frame1.validate();
140 }
141 dumpGLCanvasStats(glCanvas);
142 System.err.println("XXXX Move P2 -> P1 - END");
143 }
144 });
145 panel2.add(bMoveP2toP1, BorderLayout.NORTH);
146
147 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
148 public void run() {
149 // frame1.pack();
150 System.err.println("XXX SetVisible ON XXX GLCanvas on Panel1("+id(panel1)+")");
151 if( onlyVisibleWithCanvas ) {
152 frame1.setVisible(true);
153 } else {
154 frame1.setVisible(true);
155 frame2.setVisible(true);
156 }
157 }});
158 Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame1, true, null));
159 Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas, true, null));
160 dumpGLCanvasStats(glCanvas);
161
162 if(manual) {
163 for(long w=durationPerTest; w>0; w-=100) {
164 Thread.sleep(100);
165 }
166 } else {
167 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
168 public void run() {
169 System.err.println("XXXX Add GLCanvas Panel1("+id(panel1)+" -> Panel2("+id(panel2)+") START");
170 dumpGLCanvasStats(glCanvas);
171 panel2.add(glCanvas, BorderLayout.CENTER);
172 if( onlyVisibleWithCanvas ) {
173 frame1.setVisible(false);
174 frame2.setVisible(true);
175 frame2.toFront();
176 } else {
177 frame1.validate();
178 frame2.validate();
179 }
180 dumpGLCanvasStats(glCanvas);
181 }});
182 Thread.sleep(durationPerTest/4);
183
184 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
185 public void run() {
186 System.err.println("XXXX Add GLCanvas Panel2("+id(panel2)+") -> Panel1("+id(panel1)+" START");
187 dumpGLCanvasStats(glCanvas);
188 panel1.add(glCanvas, BorderLayout.CENTER);
189 if( onlyVisibleWithCanvas ) {
190 frame2.setVisible(false);
191 frame1.setVisible(true);
192 frame1.toFront();
193 } else {
194 frame2.validate();
195 frame1.validate();
196 }
197 dumpGLCanvasStats(glCanvas);
198 }});
199 Thread.sleep(durationPerTest/4);
200
201 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
202 public void run() {
203 System.err.println("XXXX Add GLCanvas Panel1("+id(panel1)+" -> Panel2("+id(panel2)+") START");
204 dumpGLCanvasStats(glCanvas);
205 panel2.add(glCanvas, BorderLayout.CENTER);
206 if( onlyVisibleWithCanvas ) {
207 frame1.setVisible(false);
208 frame2.setVisible(true);
209 frame2.toFront();
210 } else {
211 frame1.validate();
212 frame2.validate();
213 }
214 dumpGLCanvasStats(glCanvas);
215 }});
216 Thread.sleep(durationPerTest/4);
217
218 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
219 public void run() {
220 System.err.println("XXXX Add GLCanvas Panel2("+id(panel2)+") -> Panel1("+id(panel1)+" START");
221 dumpGLCanvasStats(glCanvas);
222 panel1.add(glCanvas, BorderLayout.CENTER);
223 if( onlyVisibleWithCanvas ) {
224 frame2.setVisible(false);
225 frame1.setVisible(true);
226 frame1.toFront();
227 } else {
228 frame2.validate();
229 frame1.validate();
230 }
231 dumpGLCanvasStats(glCanvas);
232 }});
233 Thread.sleep(durationPerTest/4);
234 }
235
236 SwingUtilities.invokeLater(new Runnable() {
237 public void run() {
238 System.err.println("XXX SetVisible OFF XXX");
239 frame1.dispose();
240 frame2.dispose();
241 } });
242 }
243
244 private static String id(final Object obj) { return "0x"+Integer.toHexString(obj.hashCode()); }
245
246 static void dumpGLCanvasStats(final GLCanvas glCanvas) {
247 System.err.println("XXXX GLCanvas: comp "+glCanvas+", visible "+glCanvas.isVisible()+", showing "+glCanvas.isShowing()+
248 ", displayable "+glCanvas.isDisplayable()+", "+glCanvas.getSurfaceWidth()+"x"+glCanvas.getSurfaceHeight());
249 }
250
251 public static void main(final String args[]) {
252 for(int i=0; i<args.length; i++) {
253 if(args[i].equals("-time")) {
254 durationPerTest = MiscUtils.atoi(args[++i], (int)durationPerTest);
255 } else if(args[i].equals("-manual")) {
256 manual = true;
257 }
258 }
259 org.junit.runner.JUnitCore.main(TestBug816GLCanvasFrameHoppingB849B889AWT.class.getName());
260 }
261
262}
Specifies a set of OpenGL capabilities.
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
static final String GL2ES2
The intersection of the desktop GL3, GL2 and embedded ES2 profile.
Definition: GLProfile.java:594
static GLProfile get(final AbstractGraphicsDevice device, String profile)
Returns a GLProfile object.
A heavyweight AWT component which provides OpenGL rendering support.
Definition: GLCanvas.java:170
void addGLEventListener(final GLEventListener listener)
Adds the given listener to the end of this drawable queue.
Definition: GLCanvas.java:1065
static int atoi(final String str, final int def)
Definition: MiscUtils.java:57
void setSize(int width, int height)
Requests a new width and height for this AWTGLAutoDrawable.