29package com.jogamp.opengl.test.junit.jogl.awt;
31import java.awt.BorderLayout;
33import java.awt.Component;
34import java.awt.Dimension;
35import java.awt.Graphics;
36import java.awt.GridLayout;
38import java.lang.Thread.UncaughtExceptionHandler;
39import java.lang.reflect.InvocationTargetException;
41import javax.swing.JFrame;
42import javax.swing.JPanel;
43import javax.swing.SwingUtilities;
45import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
46import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
47import com.jogamp.opengl.test.junit.util.MiscUtils;
48import com.jogamp.opengl.test.junit.util.UITestCase;
50import org.junit.Assert;
52import com.jogamp.common.ExceptionUtils;
53import com.jogamp.common.util.InterruptedRuntimeException;
54import com.jogamp.common.util.SourcedInterruptedException;
55import com.jogamp.nativewindow.NativeWindowFactory;
56import com.jogamp.opengl.GLAutoDrawable;
57import com.jogamp.opengl.GLEventListener;
58import com.jogamp.opengl.awt.GLCanvas;
61import org.junit.FixMethodOrder;
62import org.junit.runners.MethodSorters;
85@FixMethodOrder(MethodSorters.NAME_ASCENDING)
87 static long durationPerTest = 1000;
89 private void setVisible(
final JFrame frame,
final boolean v)
throws InterruptedException, InvocationTargetException {
90 javax.swing.SwingUtilities.invokeAndWait(
new Runnable() {
97 private void dispose(
final JFrame jFrame)
throws InterruptedException, InvocationTargetException {
98 SwingUtilities.invokeAndWait(
new Runnable() {
105 @Test(timeout=180000)
106 public
void test01_NoGL() throws InterruptedException, InvocationTargetException {
110 @Test(timeout=180000)
111 public
void test02_WithGL() throws InterruptedException, InvocationTargetException {
115 class OurUncaughtExceptionHandler
implements UncaughtExceptionHandler {
116 public volatile Thread thread =
null;
117 public volatile Throwable exception =
null;
120 public void uncaughtException(
final Thread t,
final Throwable e) {
123 System.err.println(
"*** UncaughtException (this Thread "+Thread.currentThread().getName()+
") : Thread <"+t.getName()+
">, "+e.getClass().getName()+
": "+e.getMessage());
124 ExceptionUtils.dumpThrowable(
"", e);
127 void testImpl(
final boolean useGL)
throws InterruptedException, InvocationTargetException {
128 if( !AWTRobotUtil.isAWTEDTAlive() ) {
129 System.err.println(
"Test aborted: AWT not alive");
134 final OurUncaughtExceptionHandler uncaughtHandler =
new OurUncaughtExceptionHandler();
135 Thread.setDefaultUncaughtExceptionHandler( uncaughtHandler );
137 final Dimension csize =
new Dimension(800, 400);
138 final JPanel panel =
new JPanel(
new GridLayout(2, 1));
140 final InterruptableGLEL iglel;
142 glc =
new GLCanvas();
144 final GearsES2 gears =
new GearsES2();
145 gears.setVerbose(
false);
146 glc.addGLEventListener(gears);
148 iglel =
new InterruptableGLEL();
149 glc.addGLEventListener(iglel);
151 glc.setPreferredSize(csize);
154 NativeWindowFactory.initSingleton();
157 final Label l =
new Label(
"No GL Object");
159 l.setPreferredSize(csize);
162 final InterruptingComponent icomp =
new InterruptingComponent();
164 icomp.setSize(csize);
165 icomp.setPreferredSize(csize);
167 final JFrame frame =
new JFrame();
168 frame.setResizable(
true);
169 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
171 frame.getContentPane().add(panel, BorderLayout.CENTER);
172 setVisible(frame,
true);
174 Assert.assertTrue(AWTRobotUtil.waitForRealized(glc,
true,
null));
176 Assert.assertTrue(AWTRobotUtil.waitForRealized(icomp,
true,
null));
178 final InterruptableLoop loop =
new InterruptableLoop(icomp, glc);
179 final Thread thread =
new Thread(loop);
185 while( !loop.isRunning && !loop.shallStop ) {
190 }
catch (
final InterruptedException e) {
191 Assert.assertNull(
"while starting loop",
new InterruptedRuntimeException(e));
195 for(
int i=0; thread.isAlive() &&
null == loop.exception &&
null == uncaughtHandler.exception && i<100; i++) {
196 icomp.interruptAWTEventQueue();
197 Thread.sleep(durationPerTest/100);
200 loop.shallStop =
true;
204 while( loop.isRunning ) {
207 }
catch (
final InterruptedException e) {
208 Assert.assertNull(
"while stopping loop",
new InterruptedRuntimeException(e));
219 if(
null != iglel &&
null != iglel.exception ) {
220 ExceptionUtils.dumpThrowable(
"GLEventListener", iglel.exception);
222 if(
null != icomp.exception ) {
223 ExceptionUtils.dumpThrowable(
"InterruptingComponent", icomp.exception);
225 if(
null != loop.exception ) {
226 ExceptionUtils.dumpThrowable(
"loop", loop.exception);
228 if(
null != uncaughtHandler.exception ) {
229 ExceptionUtils.dumpThrowable(
"uncaughtHandler", uncaughtHandler.exception);
231 if( !AWTRobotUtil.isAWTEDTAlive() ) {
232 System.err.println(
"AWT is not alive anymore!!! Ooops");
241 Assert.assertNull(
"Caught Exception in loop", loop.exception);
242 Assert.assertNull(
"Caught Exception via uncaughtHandler", uncaughtHandler.exception);
245 static class InterruptableLoop
implements Runnable {
246 public volatile Exception exception =
null;
247 public volatile boolean shallStop =
false;
248 public volatile boolean isRunning =
false;
249 public volatile boolean ack =
false;
250 final InterruptingComponent icomp;
252 boolean alt =
false;;
254 InterruptableLoop(
final InterruptingComponent icomp,
final GLCanvas glc) {
266 synchronized ( this ) {
274 }
catch (
final InterruptedException e) {
275 throw new InterruptedRuntimeException(e);
279 synchronized ( this ) {
281 while( !shallStop ) {
284 }
else if(
null != glc ) {
290 if( Thread.interrupted() ) {
291 final InterruptedRuntimeException e =
new InterruptedRuntimeException(
new InterruptedException(
"Interrupt detected in loop, thread: "+Thread.currentThread().getName()));
295 }
catch (
final InterruptedException e) {
296 exception = SourcedInterruptedException.wrap(e);
297 ExceptionUtils.dumpThrowable(
"", exception);
298 }
catch (
final Exception e) {
300 ExceptionUtils.dumpThrowable(
"", exception);
309 static class InterruptableGLEL
implements GLEventListener {
310 public volatile InterruptedException exception =
null;
312 public void init(
final GLAutoDrawable drawable) {
315 public void dispose(
final GLAutoDrawable drawable) {
318 public void display(
final GLAutoDrawable drawable) {
319 final Thread c = Thread.currentThread();
320 if( c.isInterrupted() &&
null == exception ) {
321 exception =
new InterruptedException(
"Interrupt detected in GLEventListener, thread: "+c.getName());
322 drawable.removeGLEventListener(
this);
326 public void reshape(
final GLAutoDrawable drawable,
final int x,
final int y,
final int width,
final int height) {
330 static class InterruptingComponent
extends Component {
331 private static final long serialVersionUID = 1L;
332 public volatile InterruptedException exception =
null;
334 private volatile boolean doInterrupt =
false;
336 private final Color[] colors =
337 new Color[] { Color.BLACK, Color.BLUE, Color.DARK_GRAY, Color.GRAY, Color.LIGHT_GRAY };
338 private int colorIdx = 0;
340 public InterruptingComponent() {
343 public void interruptAWTEventQueue() {
348 public void paint(
final Graphics g)
350 final Thread c = Thread.currentThread();
351 if( c.isInterrupted() &&
null == exception ) {
352 exception =
new InterruptedException(
"Interrupt detected in AWT Component, thread: "+c.getName());
355 g.setColor(colors[colorIdx++]);
356 if( colorIdx >= colors.length ) {
359 g.fillRect(0, 0, getWidth(), getHeight());
362 System.err.println(
"Thread "+c.getName()+
": *Interrupting*");
369 public static void main(
final String[] args) {
370 for(
int i=0; i<args.length; i++) {
371 if(args[i].equals(
"-time")) {
372 durationPerTest =
MiscUtils.
atol(args[++i], durationPerTest);
Test to check if interrupt on AWT-EventQueue causes a malfunction in JOGL.
static void main(final String[] args)
static long atol(final String str, final long def)