From 50f997557b91a2f014ef0c2ea848c5c326d0cfb2 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 19 Jan 2013 07:04:56 +0100 Subject: NEWT/Android: Full Lifecycle for WindowDriver; Using static ViewGroup; AWTRobotUtil: More tolerant for non AWT env.; Fix adb-launch-* - NEWT/Android WindowDriver - Full Lifecycle, remove refs on closeNative() - Respect isFullscreen() - Using static ViewGroup if available and surface not ready, allows running from main() - AWTRobotUtil: More tolerant for non AWT env. - Check for NEWT first - Only use AWT iff available, which allows running on Android - Fix adb-launch-* - Launch main/junit tests --- src/newt/classes/jogamp/newt/WindowImpl.java | 7 +- .../jogamp/newt/driver/android/WindowDriver.java | 177 +++++++++++---- .../test/android/NEWTGearsES2ActivityLauncher.java | 6 +- .../opengl/test/junit/jogl/demos/es2/GearsES2.java | 1 - .../opengl/test/junit/util/AWTRobotUtil.java | 239 ++++++++++----------- 5 files changed, 252 insertions(+), 178 deletions(-) (limited to 'src') diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 3c93de5b3..89c3bada6 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -278,12 +278,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer boolean postParentlockFocus = false; try { if(validateParentWindowHandle()) { - if(screenReferenceAdded) { - throw new InternalError("XXX"); - } - if(canCreateNativeImpl()) { + if( !screenReferenceAdded ) { screen.addReference(); screenReferenceAdded = true; + } + if(canCreateNativeImpl()) { createNativeImpl(); screen.addScreenModeListener(screenModeListenerImpl); setTitleImpl(title); diff --git a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java index 281bd9e0f..ba5d09759 100644 --- a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java @@ -29,6 +29,7 @@ package jogamp.newt.driver.android; import jogamp.common.os.android.StaticContext; +import jogamp.newt.WindowImpl; import jogamp.newt.driver.android.event.AndroidNewtEventTranslator; import javax.media.nativewindow.Capabilities; @@ -43,6 +44,8 @@ import javax.media.opengl.GLException; import com.jogamp.common.os.AndroidVersion; import com.jogamp.nativewindow.egl.EGLGraphicsDevice; +import com.jogamp.newt.Screen; +import com.jogamp.newt.ScreenMode; import jogamp.opengl.egl.EGL; import jogamp.opengl.egl.EGLGraphicsConfiguration; @@ -52,11 +55,14 @@ import android.content.Context; import android.graphics.PixelFormat; import android.os.Bundle; import android.os.IBinder; +import android.os.Looper; import android.os.ResultReceiver; import android.util.Log; +import android.view.Gravity; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback2; +import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.view.SurfaceView; @@ -65,7 +71,7 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 { DisplayDriver.initSingleton(); } - public static CapabilitiesImmutable fixCaps(boolean matchFormatPrecise, int format, CapabilitiesImmutable rCaps) { + public static final CapabilitiesImmutable fixCaps(boolean matchFormatPrecise, int format, CapabilitiesImmutable rCaps) { PixelFormat pf = new PixelFormat(); PixelFormat.getPixelFormatInfo(format, pf); final CapabilitiesImmutable res; @@ -104,7 +110,7 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 { return res; } - public static int getFormat(CapabilitiesImmutable rCaps) { + public static final int getFormat(CapabilitiesImmutable rCaps) { int fmt = PixelFormat.UNKNOWN; if(!rCaps.isBackgroundOpaque()) { @@ -130,7 +136,7 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 { return fmt; } - public static boolean isAndroidFormatTransparent(int aFormat) { + public static final boolean isAndroidFormatTransparent(int aFormat) { switch (aFormat) { case PixelFormat.TRANSLUCENT: case PixelFormat.TRANSPARENT: @@ -147,8 +153,8 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 { reset(); } - private void reset() { - ownAndroidWindow = false; + private final void reset() { + added2StaticViewGroup = false; androidView = null; nativeFormat = VisualIDHolder.VID_UNDEFINED; androidFormat = VisualIDHolder.VID_UNDEFINED; @@ -157,10 +163,12 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 { surfaceHandle = 0; eglSurface = 0; definePosition(0, 0); // default to 0/0 + defineSize(0, 0); // default size -> TBD ! + setBrokenFocusChange(true); } - private void setupInputListener(boolean enable) { + private final void setupInputListener(final boolean enable) { Log.d(MD.TAG, "setupInputListener(enable "+enable+") - "+Thread.currentThread().getName()); final AndroidNewtEventTranslator eventTranslator = @@ -169,51 +177,104 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 { androidView.setOnKeyListener(eventTranslator); androidView.setOnFocusChangeListener(eventTranslator); if(AndroidVersion.SDK_INT >= 12) { // API Level 12 - Log.d(MD.TAG, "instantiationFinished() - enable GenericMotionListener - "+Thread.currentThread().getName()); + Log.d(MD.TAG, "setupInputListener - enable GenericMotionListener - "+Thread.currentThread().getName()); androidView.setOnGenericMotionListener(eventTranslator); } - androidView.setClickable(false); - androidView.setFocusable(enable); - androidView.setFocusableInTouchMode(enable); + if( enable ) { + androidView.post(new Runnable() { + public void run() { + androidView.setClickable(false); + androidView.setFocusable(true); + androidView.setFocusableInTouchMode(true); + } } ); + } } + private final void setupAndroidView(Context ctx) { + androidView = new MSurfaceView(ctx); + + final SurfaceHolder sh = androidView.getHolder(); + sh.addCallback(WindowDriver.this); + sh.setFormat(getFormat(getRequestedCapabilities())); + } + private final void removeAndroidView() { + final SurfaceHolder sh = androidView.getHolder(); + sh.removeCallback(WindowDriver.this); + androidView = null; + } + + public final SurfaceView getAndroidView() { return androidView; } + @Override - protected void instantiationFinished() { + protected final void instantiationFinished() { Log.d(MD.TAG, "instantiationFinished() - "+Thread.currentThread().getName()); - + final Context ctx = StaticContext.getContext(); if(null == ctx) { throw new NativeWindowException("No static [Application] Context has been set. Call StaticContext.setContext(Context) first."); } - androidView = new MSurfaceView(ctx); - - final SurfaceHolder sh = androidView.getHolder(); - sh.addCallback(WindowDriver.this); - sh.setFormat(getFormat(getRequestedCapabilities())); - // default size -> TBD ! - defineSize(0, 0); + if( null != Looper.myLooper() ) { + setupAndroidView(ctx); + } } - public final SurfaceView getAndroidView() { return androidView; } - @Override - protected boolean canCreateNativeImpl() { - final boolean b = 0 != surfaceHandle; - Log.d(MD.TAG, "canCreateNativeImpl: "+b); + protected final boolean canCreateNativeImpl() { + Log.d(MD.TAG, "canCreateNativeImpl.0: surfaceHandle ready "+(0!=surfaceHandle)+" - on thread "+Thread.currentThread().getName()); + if(WindowImpl.DEBUG_IMPLEMENTATION) { + Thread.dumpStack(); + } + + if( isFullscreen() ) { + final Screen screen = getScreen(); + final ScreenMode sm = screen.getCurrentScreenMode(); + definePosition(screen.getX(), screen.getY()); + defineSize(sm.getRotatedWidth(), sm.getRotatedHeight()); + } + + final boolean b; + + if( 0 == surfaceHandle ) { + // Static ViewGroup, i.e. self contained main code + final ViewGroup viewGroup = StaticContext.getContentViewGroup(); + Log.d(MD.TAG, "canCreateNativeImpl: viewGroup "+viewGroup); + if( null != viewGroup && !added2StaticViewGroup ) { + added2StaticViewGroup = true; + viewGroup.post(new Runnable() { + public void run() { + if(null == androidView) { + setupAndroidView( StaticContext.getContext() ); + } + viewGroup.addView(androidView, new android.widget.FrameLayout.LayoutParams(getWidth(), getHeight(), Gravity.BOTTOM|Gravity.RIGHT)); + Log.d(MD.TAG, "canCreateNativeImpl: added to static ViewGroup - on thread "+Thread.currentThread().getName()); + } }); + for(long sleep = TIMEOUT_NATIVEWINDOW; 0 "+aFormat+", "+aWidth+"x"+aHeight+", current surfaceHandle: 0x"+Long.toHexString(surfaceHandle)); + public final void surfaceChanged(SurfaceHolder aHolder, int aFormat, int aWidth, int aHeight) { + Log.d(MD.TAG, "surfaceChanged: f "+nativeFormat+" -> "+aFormat+", "+aWidth+"x"+aHeight+", current surfaceHandle: 0x"+Long.toHexString(surfaceHandle)+" - on thread "+Thread.currentThread().getName()); + if(WindowImpl.DEBUG_IMPLEMENTATION) { + Thread.dumpStack(); + } if(0!=surfaceHandle && androidFormat != aFormat ) { // re-create Log.d(MD.TAG, "surfaceChanged (destroy old)"); @@ -437,18 +525,21 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 { } @Override - public void surfaceDestroyed(SurfaceHolder holder) { - Log.d(MD.TAG, "surfaceDestroyed"); + public final void surfaceDestroyed(SurfaceHolder holder) { + Log.d(MD.TAG, "surfaceDestroyed - on thread "+Thread.currentThread().getName()); + if(WindowImpl.DEBUG_IMPLEMENTATION) { + Thread.dumpStack(); + } windowDestroyNotify(true); // actually too late .. however .. } @Override - public void surfaceRedrawNeeded(SurfaceHolder holder) { - Log.d(MD.TAG, "surfaceRedrawNeeded"); + public final void surfaceRedrawNeeded(SurfaceHolder holder) { + Log.d(MD.TAG, "surfaceRedrawNeeded - on thread "+Thread.currentThread().getName()); windowRepaint(0, 0, getWidth(), getHeight()); } - private boolean ownAndroidWindow; + private boolean added2StaticViewGroup; private MSurfaceView androidView; private int nativeFormat; // chosen current native PixelFormat (suitable for EGL) private int androidFormat; // chosen current android PixelFormat (-1, -2 ..) diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java index 415efc7f2..7138ba805 100644 --- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java +++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java @@ -49,7 +49,7 @@ public class NEWTGearsES2ActivityLauncher extends LauncherUtil.BaseActivityLaunc props.setProperty("nativewindow.debug.GraphicsConfiguration", "true"); // props.setProperty("jogl.debug", "all"); // properties.setProperty("jogl.debug.GLProfile", "true"); - props.setProperty("jogl.debug.GLDrawable", "true"); + // props.setProperty("jogl.debug.GLDrawable", "true"); props.setProperty("jogl.debug.GLContext", "true"); props.setProperty("jogl.debug.GLSLCode", "true"); // props.setProperty("jogl.debug.CapabilitiesChooser", "true"); @@ -57,8 +57,8 @@ public class NEWTGearsES2ActivityLauncher extends LauncherUtil.BaseActivityLaunc // props.setProperty("jogl.debug.DebugGL", "true"); // props.setProperty("jogl.debug.TraceGL", "true"); // props.setProperty("newt.debug", "all"); - // props.setProperty("newt.debug.Window", "true"); - // props.setProperty("newt.debug.Window.MouseEvent", "true"); + props.setProperty("newt.debug.Window", "true"); + props.setProperty("newt.debug.Window.MouseEvent", "true"); props.setProperty("newt.debug.Window.KeyEvent", "true"); } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java index 43a393495..74377a5f8 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java @@ -25,7 +25,6 @@ import com.jogamp.newt.Window; import com.jogamp.newt.event.KeyAdapter; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.KeyListener; -import com.jogamp.newt.event.MouseAdapter; import com.jogamp.newt.event.MouseEvent; import com.jogamp.newt.event.MouseListener; import com.jogamp.opengl.test.junit.jogl.demos.GearsObject; diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java index 45648bedf..ffc42e318 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java +++ b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java @@ -32,13 +32,10 @@ import jogamp.newt.WindowImplAccess; import java.lang.reflect.InvocationTargetException; import java.awt.AWTException; -import java.awt.Component; -import java.awt.EventQueue; -import java.awt.KeyboardFocusManager; import java.awt.Robot; -import java.awt.Toolkit; import javax.media.nativewindow.NativeWindow; +import javax.media.nativewindow.NativeWindowFactory; import javax.media.opengl.GLDrawable; import javax.media.opengl.awt.GLCanvas; @@ -63,77 +60,69 @@ public class AWTRobotUtil { javax.swing.SwingUtilities.invokeAndWait(new Runnable() { public void run() { System.err.println("******** clearAWTFocus.0"); - KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner(); + java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner(); }}); robot.delay(ROBOT_DELAY); System.err.println("******** clearAWTFocus.X"); } - public static java.awt.Point getCenterLocation(Object obj, boolean onTitleBarIfWindow) + public static int[] getCenterLocation(Object obj, boolean onTitleBarIfWindow) throws InterruptedException, InvocationTargetException { - Component comp = null; - com.jogamp.newt.Window win = null; - if(obj instanceof com.jogamp.newt.Window) { - win = (com.jogamp.newt.Window) obj; - } else if(obj instanceof Component) { - comp = (Component) obj; + return getCenterLocationNEWT((com.jogamp.newt.Window)obj, onTitleBarIfWindow); + } else if(NativeWindowFactory.isAWTAvailable() && obj instanceof java.awt.Component) { + return getCenterLocationAWT((java.awt.Component)obj, onTitleBarIfWindow); } else { throw new RuntimeException("Neither AWT nor NEWT: "+obj); - } + } + } + private static int[] getCenterLocationNEWT(com.jogamp.newt.Window win, boolean onTitleBarIfWindow) + throws InterruptedException, InvocationTargetException { + javax.media.nativewindow.util.Point p0 = win.getLocationOnScreen(null); + if( onTitleBarIfWindow ) { + javax.media.nativewindow.util.InsetsImmutable insets = win.getInsets(); + p0.translate(win.getWidth()/2, insets.getTopHeight()/2); + } else { + p0.translate(win.getWidth()/2, win.getHeight()/2); + } + return new int[] { p0.getX(), p0.getY() }; + } + private static int[] getCenterLocationAWT(java.awt.Component comp, boolean onTitleBarIfWindow) + throws InterruptedException, InvocationTargetException { int x0, y0; - if(null!=comp) { - java.awt.Point p0 = comp.getLocationOnScreen(); - java.awt.Rectangle r0 = comp.getBounds(); - if( onTitleBarIfWindow && comp instanceof java.awt.Window) { - java.awt.Window window = (java.awt.Window) comp; - java.awt.Insets insets = window.getInsets(); - y0 = (int) ( p0.getY() + insets.top / 2.0 + .5 ) ; - } else { - y0 = (int) ( p0.getY() + r0.getHeight() / 2.0 + .5 ) ; - } - x0 = (int) ( p0.getX() + r0.getWidth() / 2.0 + .5 ) ; + java.awt.Point p0 = comp.getLocationOnScreen(); + java.awt.Rectangle r0 = comp.getBounds(); + if( onTitleBarIfWindow && comp instanceof java.awt.Window) { + java.awt.Window window = (java.awt.Window) comp; + java.awt.Insets insets = window.getInsets(); + y0 = (int) ( p0.getY() + insets.top / 2.0 + .5 ) ; } else { - javax.media.nativewindow.util.Point p0 = win.getLocationOnScreen(null); - if( onTitleBarIfWindow ) { - javax.media.nativewindow.util.InsetsImmutable insets = win.getInsets(); - p0.translate(win.getWidth()/2, insets.getTopHeight()/2); - } else { - p0.translate(win.getWidth()/2, win.getHeight()/2); - } - x0 = p0.getX(); - y0 = p0.getY(); + y0 = (int) ( p0.getY() + r0.getHeight() / 2.0 + .5 ) ; } - - return new java.awt.Point(x0, y0); + x0 = (int) ( p0.getX() + r0.getWidth() / 2.0 + .5 ) ; + return new int[] { x0, y0 }; } - public static java.awt.Point getClientLocation(Object obj, int x, int y) + public static int[] getClientLocation(Object obj, int x, int y) throws InterruptedException, InvocationTargetException { - Component comp = null; - com.jogamp.newt.Window win = null; - if(obj instanceof com.jogamp.newt.Window) { - win = (com.jogamp.newt.Window) obj; - } else if(obj instanceof Component) { - comp = (Component) obj; + return getClientLocationNEWT((com.jogamp.newt.Window)obj, x, y); + } else if(NativeWindowFactory.isAWTAvailable() && obj instanceof java.awt.Component) { + return getClientLocationAWT((java.awt.Component)obj, x, y); } else { throw new RuntimeException("Neither AWT nor NEWT: "+obj); - } - - int x0, y0; - if(null!=comp) { - java.awt.Point p0 = comp.getLocationOnScreen(); - x0 = (int) p0.getX() + x; - y0 = (int) p0.getY() + y; - } else { - javax.media.nativewindow.util.Point p0 = win.getLocationOnScreen(null); - x0 = p0.getX() + x; - y0 = p0.getY() + y; - } - - return new java.awt.Point(x0, y0); + } + } + private static int[] getClientLocationNEWT(com.jogamp.newt.Window win, int x, int y) + throws InterruptedException, InvocationTargetException { + javax.media.nativewindow.util.Point p0 = win.getLocationOnScreen(null); + return new int[] { p0.getX(), p0.getY() }; + } + private static int[] getClientLocationAWT(java.awt.Component comp, int x, int y) + throws InterruptedException, InvocationTargetException { + java.awt.Point p0 = comp.getLocationOnScreen(); + return new int[] { (int)p0.getX(), (int)p0.getY() }; } /** @@ -154,9 +143,9 @@ public class AWTRobotUtil { robot = new Robot(); robot.setAutoWaitForIdle(true); } - java.awt.Point p0 = getCenterLocation(window, false); - System.err.println("toFront: robot pos: "+p0); - robot.mouseMove( (int) p0.getX(), (int) p0.getY() ); + int[] p0 = getCenterLocation(window, false); + System.err.println("toFront: robot pos: "+p0[0]+"x"+p0[1]); + robot.mouseMove( p0[0], p0[1] ); robot.delay(ROBOT_DELAY); int wait=0; @@ -197,10 +186,10 @@ public class AWTRobotUtil { robot.setAutoWaitForIdle(true); } - java.awt.Point p0 = getCenterLocation(obj, onTitleBarIfWindow); - System.err.println("centerMouse: robot pos: "+p0+", onTitleBarIfWindow: "+onTitleBarIfWindow); + int[] p0 = getCenterLocation(obj, onTitleBarIfWindow); + System.err.println("centerMouse: robot pos: "+p0[0]+"x"+p0[1]+", onTitleBarIfWindow: "+onTitleBarIfWindow); - robot.mouseMove( (int) p0.getX(), (int) p0.getY() ); + robot.mouseMove( p0[0], p0[1] ); robot.delay(ROBOT_DELAY); } @@ -212,19 +201,19 @@ public class AWTRobotUtil { robot.setAutoWaitForIdle(true); } - java.awt.Point p0 = getClientLocation(obj, x, y); + int[] p0 = getClientLocation(obj, x, y); - robot.mouseMove( (int) p0.getX(), (int) p0.getY() ); + robot.mouseMove( p0[0], p0[1] ); robot.delay(ROBOT_DELAY); } public static int getClickTimeout(Object obj) { if(obj instanceof com.jogamp.newt.Window) { return com.jogamp.newt.event.MouseEvent.getClickTimeout(); - } else if(obj instanceof Component) { + } else if(NativeWindowFactory.isAWTAvailable() && obj instanceof java.awt.Component) { if(null == AWT_CLICK_TO) { AWT_CLICK_TO = - (Integer) Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval"); + (Integer) java.awt.Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval"); if(null == AWT_CLICK_TO) { AWT_CLICK_TO = new Integer(500); } @@ -250,32 +239,7 @@ public class AWTRobotUtil { */ public static void requestFocus(Robot robot, Object obj, boolean onTitleBarIfWindow) throws AWTException, InterruptedException, InvocationTargetException { - - final Component comp; - final com.jogamp.newt.Window win; - - if(obj instanceof com.jogamp.newt.Window) { - win = (com.jogamp.newt.Window) obj; - comp = null; - } else if(obj instanceof Component) { - win = null; - comp = (Component) obj; - } else { - throw new RuntimeException("Neither AWT nor NEWT: "+obj); - } - - if(null == robot) { - if(null!=comp) { - javax.swing.SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - comp.requestFocus(); - System.err.println("requestFocus: AWT Component"); - }}); - } else { - win.requestFocus(); - System.err.println("requestFocus: NEWT Component"); - } - } else { + if(null != robot) { final int mouseButton = java.awt.event.InputEvent.BUTTON1_MASK; centerMouse(robot, obj, onTitleBarIfWindow); @@ -284,9 +248,30 @@ public class AWTRobotUtil { robot.mouseRelease(mouseButton); final int d = getClickTimeout(obj) + 1; robot.delay( d ); - System.err.println("requestFocus: click, d: "+d+" ms"); + System.err.println("requestFocus: click, d: "+d+" ms"); + } else { + if(obj instanceof com.jogamp.newt.Window) { + requestFocusNEWT((com.jogamp.newt.Window) obj, onTitleBarIfWindow); + } else if(NativeWindowFactory.isAWTAvailable() && obj instanceof java.awt.Component) { + requestFocusAWT((java.awt.Component) obj, onTitleBarIfWindow); + } else { + throw new RuntimeException("Neither AWT nor NEWT: "+obj); + } } } + private static void requestFocusNEWT(com.jogamp.newt.Window win, boolean onTitleBarIfWindow) + throws AWTException, InterruptedException, InvocationTargetException { + win.requestFocus(); + System.err.println("requestFocus: NEWT Component"); + } + private static void requestFocusAWT(final java.awt.Component comp, boolean onTitleBarIfWindow) + throws AWTException, InterruptedException, InvocationTargetException { + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + comp.requestFocus(); + System.err.println("requestFocus: AWT Component"); + }}); + } public static void requestFocus(Robot robot, Object obj, int x, int y) throws AWTException, InterruptedException, InvocationTargetException { @@ -306,12 +291,12 @@ public class AWTRobotUtil { } public static boolean hasFocus(Object obj) { - if(obj instanceof Component) { - final Component comp = (Component) obj; - final KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); - return comp == kfm.getPermanentFocusOwner(); - } else if(obj instanceof com.jogamp.newt.Window) { + if(obj instanceof com.jogamp.newt.Window) { return ((com.jogamp.newt.Window) obj).hasFocus(); + } else if(NativeWindowFactory.isAWTAvailable() && obj instanceof java.awt.Component) { + final java.awt.Component comp = (java.awt.Component) obj; + final java.awt.KeyboardFocusManager kfm = java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager(); + return comp == kfm.getPermanentFocusOwner(); } else { throw new RuntimeException("Neither AWT nor NEWT: "+obj); } @@ -323,17 +308,17 @@ public class AWTRobotUtil { */ public static boolean waitForFocus(Object obj) throws InterruptedException { int wait; - if(obj instanceof Component) { - final Component comp = (Component) obj; - final KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); - for (wait=0; wait