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 29 package com.jogamp.opengl.test.junit.newt; 30 31 import org.junit.Test; 32 import org.junit.FixMethodOrder; 33 import org.junit.runners.MethodSorters; 34 import org.junit.Assert; 35 36 import java.lang.reflect.InvocationTargetException; 37 38 import javax.swing.JFrame; 39 import javax.swing.SwingUtilities; 40 import javax.swing.WindowConstants; 41 import com.jogamp.nativewindow.NativeWindow; 42 import com.jogamp.nativewindow.util.Point; 43 import com.jogamp.opengl.GLCapabilities; 44 import com.jogamp.opengl.GLProfile; 45 46 import com.jogamp.newt.Window; 47 import com.jogamp.newt.awt.NewtCanvasAWT; 48 import com.jogamp.newt.opengl.GLWindow; 49 import com.jogamp.opengl.test.junit.util.AWTRobotUtil; 50 import com.jogamp.opengl.test.junit.util.UITestCase; 51 import com.jogamp.opengl.test.junit.util.AWTRobotUtil.WindowClosingListener; 52 53 @FixMethodOrder(MethodSorters.NAME_ASCENDING) 54 public class TestCloseNewtAWT extends UITestCase { 55 56 GLWindow newtWindow = null; 57 NewtCanvasAWT newtCanvas = null; 58 JFrame frame = null; 59 60 @SuppressWarnings("serial") 61 class MyCanvas extends NewtCanvasAWT { MyCanvas(final Window window)62 public MyCanvas(final Window window) { 63 super(window); 64 } 65 addNotify()66 public void addNotify() { 67 System.err.println("MyCanvas START add: "+Thread.currentThread()+", holds AWTTreeLock: "+Thread.holdsLock(this.getTreeLock())); 68 super.addNotify(); 69 System.err.println("MyCanvas END add: "+Thread.currentThread()+", holds AWTTreeLock: "+Thread.holdsLock(this.getTreeLock())); 70 } 71 removeNotify()72 public void removeNotify() { 73 System.err.println("MyCanvas START remove: "+Thread.currentThread()+", holds AWTTreeLock: "+Thread.holdsLock(this.getTreeLock())); 74 75 // trigger critical situation around the AWT TreeLock 76 newtWindow.runOnEDTIfAvail(true, new Runnable() { 77 public void run() { 78 // NEWT EDT while AWT is locked 79 System.err.println("MyCanvas On NEWT-EDT From AWT-EDT: "+Thread.currentThread()+ 80 ", holds AWTTreeLock: "+Thread.holdsLock(MyCanvas.this.getTreeLock())); 81 82 // Critical: Within NEWT EDT, while AWT is locked 83 final NativeWindow nw = MyCanvas.this.getNativeWindow(); 84 if(null != nw) { 85 final Point p = nw.getLocationOnScreen(null); 86 System.err.println("MyCanvas On NEWT-EDT: position: "+p); 87 } else { 88 System.err.println("MyCanvas On NEWT-EDT: position n/a, null NativeWindow"); 89 } 90 } 91 }); 92 System.err.println("MyCanvas passed critical: "+Thread.currentThread()+", holds AWTTreeLock: "+Thread.holdsLock(this.getTreeLock())); 93 94 super.removeNotify(); 95 96 System.err.println("MyCanvas END remove: "+Thread.currentThread()+", holds AWTTreeLock: "+Thread.holdsLock(this.getTreeLock())); 97 } 98 } 99 100 @Test testCloseNewtAWT()101 public void testCloseNewtAWT() throws InterruptedException, InvocationTargetException { 102 newtWindow = GLWindow.create(new GLCapabilities(GLProfile.getDefault())); 103 newtCanvas = new MyCanvas(newtWindow); 104 105 SwingUtilities.invokeAndWait(new Runnable() { 106 public void run() { 107 frame = new JFrame("NEWT Close Test"); 108 frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 109 frame.getContentPane().add(newtCanvas); 110 frame.pack(); 111 frame.setSize(800, 600); 112 frame.setVisible(true); 113 } 114 }); 115 Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); 116 Assert.assertEquals(true, AWTRobotUtil.waitForRealized(newtWindow, true)); 117 final WindowClosingListener closingListener = AWTRobotUtil.addClosingListener(frame); 118 119 Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, true, closingListener)); 120 } 121 main(final String[] args)122 public static void main(final String[] args) { 123 final String tstname = TestCloseNewtAWT.class.getName(); 124 org.junit.runner.JUnitCore.main(tstname); 125 } 126 127 } 128