JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
TestBug1245JTabbedPanelCrashAWT.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.Dimension;
32import java.awt.GridLayout;
33import java.lang.reflect.InvocationTargetException;
34
35import javax.swing.JFrame;
36import javax.swing.JPanel;
37import javax.swing.JTabbedPane;
38import javax.swing.SwingUtilities;
39import javax.swing.UIManager;
40
41import org.junit.Assert;
42import org.junit.BeforeClass;
43import org.junit.FixMethodOrder;
44import org.junit.Test;
45import org.junit.runners.MethodSorters;
46
47import com.jogamp.opengl.GLEventListener;
48import com.jogamp.opengl.GLProfile;
49import com.jogamp.opengl.awt.GLCanvas;
50import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
51import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
52import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
53import com.jogamp.opengl.test.junit.util.GLEventListenerCounter;
54import com.jogamp.opengl.test.junit.util.MiscUtils;
55import com.jogamp.opengl.test.junit.util.UITestCase;
56import com.jogamp.opengl.util.Animator;
57
58/**
59 * Bug 1245
60 * <p>
61 * https://jogamp.org/bugzilla/show_bug.cgi?id=1245
62 * </p>
63 */
64@FixMethodOrder(MethodSorters.NAME_ASCENDING)
66
67 static long durationPerTest = 500*4; // ms
68 static boolean manual = false;
69
70 @SuppressWarnings("serial")
71 static class View3D extends JPanel {
72 final GLCanvas canvas;
73 final Animator animator;
74 final int num;
75
76 public View3D(final int num) {
77 this.num = num;
78 this.setLayout(new BorderLayout());
79 canvas = new GLCanvas();
80 canvas.setSize(new Dimension(100, 100));
81 canvas.setMinimumSize(new Dimension(100, 100));
82 add(canvas, BorderLayout.CENTER);
83 animator = new Animator();
84 animator.add(canvas);
85 // could do animator.start() here as well,
86 // just to be nice - we start/stop at add/remove Notify
87 }
88 @Override
89 public void addNotify() {
90 System.err.println("View3D["+num+"].addNotify()");
91 super.addNotify();
92 if( null != animator ) {
93 animator.start();
94 }
95 }
96 @Override
97 public void removeNotify() {
98 System.err.println("View3D["+num+"].removeNotify()");
99 if( null != animator ) {
100 animator.stop();
101 }
102 super.removeNotify();
103 }
104
105 public String getGLCanvasStats() {
106 return "GLCanvas: comp "+canvas.getBounds()+", visible "+canvas.isVisible()+", showing "+canvas.isShowing()+
107 ", displayable "+canvas.isDisplayable()+", "+canvas.getSurfaceWidth()+"x"+canvas.getSurfaceHeight()+
108 ", "+canvas.getChosenGLCapabilities()+", drawable 0x"+Long.toHexString(canvas.getHandle());
109 }
110 }
111
112 final GLEventListenerCounter glelCounter = new GLEventListenerCounter();
113
114 private JTabbedPane createAndShowGUI(final JFrame frame, final View3D[] views) {
115 final JPanel panel = new JPanel(new GridLayout(1, 1));
116 final JTabbedPane tabbedPanel = new JTabbedPane();
117 for(int i=0; i<views.length; i++) {
118 final GLEventListener demo;
119 if( i%2 == 0 ) {
120 final GearsES2 gears = new GearsES2(1);
121 gears.setVerbose(false);
122 demo = gears;
123 } else {
124 final RedSquareES2 red = new RedSquareES2(1);
125 red.setVerbose(false);
126 demo = red;
127 }
128 views[i] = new View3D(i);
129 views[i].canvas.addGLEventListener(glelCounter);
130 views[i].canvas.addGLEventListener(demo);
131 tabbedPanel.addTab("Tab "+i, null, views[i], "Does nothing");
132 }
133 tabbedPanel.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
134 tabbedPanel.addChangeListener(new javax.swing.event.ChangeListener() {
135 @Override
136 public void stateChanged(final javax.swing.event.ChangeEvent evt) {
137 final int idx = tabbedPanel.getSelectedIndex();
138 if( 0 <= idx && idx < views.length ) {
139 System.err.println("Pane["+idx+"]: State Changed: "+evt);
140 System.err.println("Pane["+idx+"]: "+views[idx].getGLCanvasStats());
141 }
142 }
143 });
144
145 panel.add(tabbedPanel);
146 frame.add(panel, BorderLayout.CENTER);
147 frame.setSize(640,480);
148
149 return tabbedPanel;
150 }
151
152 private static String id(final Object obj) { return "0x"+Integer.toHexString(obj.hashCode()); }
153
154 @BeforeClass
155 public static void startup() {
157 }
158
159 @Test
160 public void test01() throws InterruptedException, InvocationTargetException {
161 final JFrame frame = new JFrame("Java3DApplication");
162 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
163
164 final View3D[] views = new View3D[4];
165 final JTabbedPane[] tabbedPane = { null };
166 SwingUtilities.invokeLater(new Runnable() {
167 @Override
168 public void run() {
169 //Turn off metal's use of bold fonts
170 UIManager.put("swing.boldMetal", Boolean.FALSE);
171 tabbedPane[0] = createAndShowGUI(frame, views);
172 System.err.println("XXX SetVisible ON XXX");
173 frame.setVisible(true);
174 } } );
175 Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true, null));
176 for(int i=0; i<views.length; i++) {
177 System.err.printf("View "+i+": "+views[i]+",%n "+views[i].getGLCanvasStats()+"%n%n");
178 }
179
180 System.err.println("XXX POST.VISIBLE: "+glelCounter);
181 if(manual) {
182 Thread.sleep(durationPerTest);
183 System.err.println("XXX POST.ACTION: "+glelCounter);
184 } else {
185 final JTabbedPane tabbedPanel = tabbedPane[0];
186
187 for(int i=0; i<views.length; i++) {
188 Thread.sleep(durationPerTest/views.length);
189 switchTab(tabbedPanel, views, i, (i+1)%views.length);
190 }
191 Thread.sleep(durationPerTest/views.length);
192 switchTab(tabbedPanel, views, 0, 1);
193
194 Thread.sleep(durationPerTest/views.length);
195 switchTab(tabbedPanel, views, 1, 0);
196
197 System.err.println("XXX POST.ACTION: "+glelCounter);
198 Assert.assertTrue(glelCounter.initCount >= views.length);
199 }
200
201 SwingUtilities.invokeLater(new Runnable() {
202 public void run() {
203 System.err.println("XXX SetVisible OFF XXX");
204 frame.dispose();
205 } });
206 Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, false, null));
207 System.err.println("XXX POST.DISPOSE: "+glelCounter);
208 }
209
210 void switchTab(final JTabbedPane tabbedPanel, final View3D[] views, final int thisId, final int nextId) throws InvocationTargetException, InterruptedException {
211 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
212 public void run() {
213 System.err.println("XXXX Panel("+id(views[thisId])+" -> Panel("+id(views[nextId])+") START");
214 tabbedPanel.setSelectedIndex(nextId);
215 }});
216 }
217
218 public static void main(final String args[]) {
219 for(int i=0; i<args.length; i++) {
220 if(args[i].equals("-time")) {
221 durationPerTest = MiscUtils.atoi(args[++i], (int)durationPerTest);
222 } else if(args[i].equals("-manual")) {
223 manual = true;
224 }
225 }
226 org.junit.runner.JUnitCore.main(TestBug1245JTabbedPanelCrashAWT.class.getName());
227 }
228}
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
static void initSingleton()
Static initialization of JOGL.
Definition: GLProfile.java:204
A heavyweight AWT component which provides OpenGL rendering support.
Definition: GLCanvas.java:170
int getSurfaceHeight()
Returns the height of this GLDrawable's surface client area in pixel units.
Definition: GLCanvas.java:1248
int getSurfaceWidth()
Returns the width of this GLDrawable's surface client area in pixel units.
Definition: GLCanvas.java:1243
long getHandle()
Returns the GL drawable handle, guaranteed to be valid after realization and while it's surface is be...
Definition: GLCanvas.java:1265
GLCapabilitiesImmutable getChosenGLCapabilities()
Fetches the GLCapabilitiesImmutable corresponding to the chosen OpenGL capabilities (pixel format / v...
Definition: GLCanvas.java:1225
static boolean waitForVisible(final java.awt.Component comp, final boolean visible, final Runnable waitAction)
static int atoi(final String str, final int def)
Definition: MiscUtils.java:57
final synchronized void add(final GLAutoDrawable drawable)
Adds a drawable to this 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
Declares events which client code can use to manage OpenGL rendering into a GLAutoDrawable.
void setSize(int width, int height)
Requests a new width and height for this AWTGLAutoDrawable.