diff options
author | Sven Gothel <[email protected]> | 2013-09-27 13:23:39 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-09-27 13:23:39 +0200 |
commit | 9a8f9b9f7e6148b60b6f0f4326df8d213774284c (patch) | |
tree | b8e060224a4a6a26cee30103fc6ae2ac0bd2e6f7 /src | |
parent | 4ef53cf2ae509a625795bfa3a8982ce75e24e83a (diff) |
Bug 816: Fix JAWTWindow's getLocationOnScreenNonBlocking(); Derive CALayer position from AWT component's location on screen. Track fixedFrame size of root CALayer; Add Split layout to unit test, add [manual] Applet tests.
- Fix JAWTWindow's getLocationOnScreenNonBlocking()
Skip JRootPane while traversing up to root Container.
JRootPane would duplicate the top-level container's offset (Window insets).
- Derive CALayer position from AWT component's location on screen. Add Split layout to unit test, add [manual] Applet tests.
AWT >= 7u40:
- AWT position is top-left w/ insets, where CALayer position is bottom/left from root CALayer w/o insets.
- Use getLocationOnScreenNonBlocking() to get location-on-screen w/o insets.
- Native code: flip origin
AWT < 7u40 still uses fixed position 0/0 for root and sub layer.
- Track fixedFrame size of root CALayer - MyCALayer:
- Override layoutSublayers to validate root and sub-layer pos/size
- Override setFrame to use fixedFrame, if set (similar to MyNSOpenGLLayer)
- Add Split layout to unit test, add [manual] Applet tests.
- Thx to 'jimthev' and 'Manu' for providing Applet unit tests
Diffstat (limited to 'src')
8 files changed, 534 insertions, 139 deletions
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java index a71356b1c..576fcf4ed 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java @@ -46,6 +46,7 @@ import java.awt.Container; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.applet.Applet; + import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.CapabilitiesImmutable; @@ -60,6 +61,7 @@ import javax.media.nativewindow.util.InsetsImmutable; import javax.media.nativewindow.util.Point; import javax.media.nativewindow.util.Rectangle; import javax.media.nativewindow.util.RectangleImmutable; +import javax.swing.JRootPane; import jogamp.nativewindow.SurfaceUpdatedHelper; import jogamp.nativewindow.jawt.JAWT; @@ -227,9 +229,6 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, if( !isOffscreenLayerSurfaceEnabled() ) { throw new NativeWindowException("Not an offscreen layer surface"); } - if(DEBUG) { - System.err.println("JAWTWindow.attachSurfaceHandle: "+toHexString(layerHandle) + ", bounds "+bounds); - } attachSurfaceLayerImpl(layerHandle); offscreenSurfaceLayer = layerHandle; component.repaint(); @@ -248,14 +247,14 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, * Call this method if any parent or ancestor's layout has been changed, * which could affects the layout of this surface. * </p> - * @see #isOffscreenLayerSurfaceEnabled() + * @see #isOffscreenLayerSurfaceEnabled() * @throws NativeWindowException if {@link #isOffscreenLayerSurfaceEnabled()} == false */ - protected void layoutSurfaceLayerImpl(long layerHandle, int width, int height) {} + protected void layoutSurfaceLayerImpl(long layerHandle) {} private final void layoutSurfaceLayerIfEnabled() throws NativeWindowException { if( isOffscreenLayerSurfaceEnabled() && 0 != offscreenSurfaceLayer ) { - layoutSurfaceLayerImpl(offscreenSurfaceLayer, getWidth(), getHeight()); + layoutSurfaceLayerImpl(offscreenSurfaceLayer); } } @@ -533,7 +532,11 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, System.err.println("Warning: JAWT Lock hold, but not the AWT tree lock: "+this); Thread.dumpStack(); } - return getLocationOnScreenNonBlocking(storage, component); + if( null == storage ) { + storage = new Point(); + } + getLocationOnScreenNonBlocking(storage, component); + return storage; } java.awt.Point awtLOS = component.getLocationOnScreen(); if(null!=storage) { @@ -569,21 +572,28 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, } protected abstract Point getLocationOnScreenNativeImpl(int x, int y); - protected static Point getLocationOnScreenNonBlocking(Point storage, Component comp) { - int x = 0; - int y = 0; + protected static Component getLocationOnScreenNonBlocking(Point storage, Component comp) { + Component last = null; while(null != comp) { - x += comp.getX(); - y += comp.getY(); + final int dx = comp.getX(); + final int dy = comp.getY(); + if( ! ( comp instanceof JRootPane ) ) { + if( DEBUG ) { + System.err.print("LOS: "+storage+" + "+comp.getClass().getSimpleName()+"["+dx+"/"+dy+"] -> "); + } + storage.translate(dx, dy); + if( DEBUG ) { + System.err.println(storage); + } + last = comp; + } else if( DEBUG ) { + System.err.println("LOS: ignore "+comp.getClass().getSimpleName()+"["+dx+"/"+dy+"]"); + } comp = comp.getParent(); } - if(null!=storage) { - storage.translate(x, y); - return storage; - } - return new Point(x, y); + return last; } - + @Override public boolean hasFocus() { return component.hasFocus(); diff --git a/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java b/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java index f38e7ea2b..e326b65bd 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java +++ b/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java @@ -28,13 +28,16 @@ package jogamp.nativewindow.awt; import java.awt.FocusTraversalPolicy; +import java.awt.Insets; import java.awt.Window; import java.awt.Component; import java.awt.Container; import java.awt.Frame; + +import javax.swing.JComponent; import javax.swing.JFrame; +import javax.swing.JRootPane; import javax.swing.WindowConstants; - import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.WindowClosingProtocol; import javax.swing.MenuSelectionManager; @@ -68,6 +71,16 @@ public class AWTMisc { } return (Container) c; } + + public static Insets getInsets(Component c) { + if( c instanceof Window ) { + return ((Window)c).getInsets(); + } + if( c instanceof JComponent ) { + return ((JComponent)c).getInsets(); + } + return null; + } public static interface ComponentAction { /** diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java index 666f895f4..6d08078b6 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java @@ -40,6 +40,7 @@ package jogamp.nativewindow.jawt.macosx; +import java.awt.Component; import java.nio.Buffer; import java.security.AccessController; import java.security.PrivilegedAction; @@ -49,11 +50,11 @@ import javax.media.nativewindow.Capabilities; import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.MutableSurface; -import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.util.Point; import com.jogamp.nativewindow.awt.JAWTWindow; +import jogamp.nativewindow.awt.AWTMisc; import jogamp.nativewindow.jawt.JAWT; import jogamp.nativewindow.jawt.JAWTFactory; import jogamp.nativewindow.jawt.JAWTUtil; @@ -105,19 +106,42 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { @Override protected void attachSurfaceLayerImpl(final long layerHandle) { OSXUtil.RunOnMainThread(false, new Runnable() { - public void run() { - OSXUtil.AddCASublayer(rootSurfaceLayer, layerHandle, getWidth(), getHeight(), JAWTUtil.getOSXCALayerQuirks()); + public void run() { + // AWT position is top-left w/ insets, where CALayer position is bottom/left from root CALayer w/o insets. + // Determine p0: components location on screen w/o insets. + // CALayer position will be determined in native code. + final Point p0 = new Point(); + final Component outterComp = getLocationOnScreenNonBlocking(p0, component); + final java.awt.Insets ins = AWTMisc.getInsets(outterComp); + if(null != ins) { + p0.translate(-ins.left, -ins.top); + } + if( DEBUG ) { + final java.awt.Point wP0 = outterComp.getLocationOnScreen(); + System.err.println("JAWTWindow.attachSurfaceHandleImpl: "+toHexString(layerHandle) + ", wP0 "+wP0+"[ins "+ins+"], p0 "+p0+", bounds "+bounds); + } + OSXUtil.AddCASublayer(rootSurfaceLayer, layerHandle, p0.getX(), p0.getY(), getWidth(), getHeight(), JAWTUtil.getOSXCALayerQuirks()); } } ); } @Override - protected void layoutSurfaceLayerImpl(long layerHandle, int width, int height) { + protected void layoutSurfaceLayerImpl(long layerHandle) { final int caLayerQuirks = JAWTUtil.getOSXCALayerQuirks(); if( 0 != caLayerQuirks ) { - if(DEBUG) { - System.err.println("JAWTWindow.layoutSurfaceLayerImpl: "+toHexString(layerHandle) + ", "+width+"x"+height+", caLayerQuirks "+caLayerQuirks+"; "+this); + // AWT position is top-left w/ insets, where CALayer position is bottom/left from root CALayer w/o insets. + // Determine p0: components location on screen w/o insets. + // CALayer position will be determined in native code. + final Point p0 = new Point(); + final Component outterComp = getLocationOnScreenNonBlocking(p0, component); + final java.awt.Insets ins = AWTMisc.getInsets(outterComp); + if( null != ins ) { + p0.translate(-ins.left, -ins.top); } - OSXUtil.FixCALayerLayout(rootSurfaceLayer, layerHandle, width, height, caLayerQuirks); + if( DEBUG ) { + final java.awt.Point wP0 = outterComp.getLocationOnScreen(); + System.err.println("JAWTWindow.layoutSurfaceLayerImpl: "+toHexString(layerHandle) + ", wP0 "+wP0+"[ins "+ins+"], p0 "+p0+", bounds "+bounds); + } + OSXUtil.FixCALayerLayout(rootSurfaceLayer, layerHandle, p0.getX(), p0.getY(), getWidth(), getHeight(), caLayerQuirks); } } @@ -312,8 +336,12 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { * </p> */ @Override - public Point getLocationOnScreen(Point storage) { - return getLocationOnScreenNonBlocking(storage, component); + public Point getLocationOnScreen(Point storage) { + if( null == storage ) { + storage = new Point(); + } + getLocationOnScreenNonBlocking(storage, component); + return storage; } protected Point getLocationOnScreenNativeImpl(final int x0, final int y0) { return null; } diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java index de24a76db..2112131ed 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java @@ -163,14 +163,14 @@ public class OSXUtil implements ToolkitProperties { * @see #CreateCALayer(int, int) * @see #RemoveCASublayer(long, long, boolean) */ - public static void AddCASublayer(final long rootCALayer, final long subCALayer, final int width, final int height, final int caLayerQuirks) { + public static void AddCASublayer(final long rootCALayer, final long subCALayer, final int x, final int y, final int width, final int height, final int caLayerQuirks) { if(0==rootCALayer || 0==subCALayer) { throw new IllegalArgumentException("rootCALayer 0x"+Long.toHexString(rootCALayer)+", subCALayer 0x"+Long.toHexString(subCALayer)); } if(DEBUG) { System.err.println("OSXUtil.AttachCALayer: caLayerQuirks "+caLayerQuirks+", 0x"+Long.toHexString(subCALayer)+" - "+Thread.currentThread().getName()); } - AddCASublayer0(rootCALayer, subCALayer, width, height, caLayerQuirks); + AddCASublayer0(rootCALayer, subCALayer, x, y, width, height, caLayerQuirks); } /** @@ -190,11 +190,11 @@ public class OSXUtil implements ToolkitProperties { * @param height the expected height * @param caLayerQuirks TODO */ - public static void FixCALayerLayout(final long rootCALayer, final long subCALayer, final int width, final int height, final int caLayerQuirks) { + public static void FixCALayerLayout(final long rootCALayer, final long subCALayer, final int x, final int y, final int width, final int height, final int caLayerQuirks) { if( 0==rootCALayer && 0==subCALayer ) { return; } - FixCALayerLayout0(rootCALayer, subCALayer, width, height, caLayerQuirks); + FixCALayerLayout0(rootCALayer, subCALayer, x, y, width, height, caLayerQuirks); } /** @@ -357,8 +357,8 @@ public class OSXUtil implements ToolkitProperties { private static native long GetNSView0(long nsWindow); private static native long GetNSWindow0(long nsView); private static native long CreateCALayer0(int width, int height); - private static native void AddCASublayer0(long rootCALayer, long subCALayer, int width, int height, int caLayerQuirks); - private static native void FixCALayerLayout0(long rootCALayer, long subCALayer, int width, int height, int caLayerQuirks); + private static native void AddCASublayer0(long rootCALayer, long subCALayer, int x, int y, int width, int height, int caLayerQuirks); + private static native void FixCALayerLayout0(long rootCALayer, long subCALayer, int x, int y, int width, int height, int caLayerQuirks); private static native void RemoveCASublayer0(long rootCALayer, long subCALayer); private static native void DestroyCALayer0(long caLayer); private static native void RunOnMainThread0(Runnable runnable); diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m index fbe37be7d..fa40c871f 100644 --- a/src/nativewindow/native/macosx/OSXmisc.m +++ b/src/nativewindow/native/macosx/OSXmisc.m @@ -333,6 +333,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSWindow0 */ @interface MyCALayer: CALayer { +@private + BOOL fixedFrameSet; + CGRect fixedFrame; } - (id)init; #ifdef DBG_LIFECYCLE @@ -341,6 +344,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSWindow0 - (void)dealloc; #endif - (id<CAAction>)actionForKey:(NSString *)key ; +- (void)layoutSublayers; +- (void)setFrame:(CGRect) frame; +- (void)fixCALayerLayout: (CALayer*) subLayer x:(jint)x y:(jint)y width:(jint)width height:(jint)height caLayerQuirks:(jint)caLayerQuirks force:(jboolean) force; @end @@ -350,6 +356,8 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSWindow0 { DBG_PRINT("MyCALayer::init.0\n"); MyCALayer * o = [super init]; + o->fixedFrameSet = 0; + o->fixedFrame = CGRectMake(0, 0, 0, 0); DBG_PRINT("MyCALayer::init.X: new %p\n", o); return o; } @@ -390,6 +398,127 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSWindow0 // return [super actionForKey: key]; } +- (void)layoutSublayers +{ + if( fixedFrameSet ) { + NSArray* subs = [self sublayers]; + if( NULL != subs ) { + CGRect rFrame = [self frame]; + if( !CGRectEqualToRect(fixedFrame, rFrame) ) { + #ifdef VERBOSE + DBG_PRINT("CALayer::layoutSublayers.0: Root %p frame %lf/%lf %lfx%lf -> %lf/%lf %lfx%lf\n", + self, + rFrame.origin.x, rFrame.origin.y, rFrame.size.width, rFrame.size.height, + fixedFrame.origin.x, fixedFrame.origin.y, fixedFrame.size.width, fixedFrame.size.height); + #endif + [super setFrame: fixedFrame]; + } + NSUInteger i = 0; + for(i=0; i<[subs count]; i++) { + CALayer* sub = [subs objectAtIndex: i]; + CGRect sFrame = [sub frame]; + CGRect sFrame2 = CGRectMake(0, 0, fixedFrame.size.width, fixedFrame.size.height); + if( !CGRectEqualToRect(sFrame2, sFrame) ) { + #ifdef VERBOSE + DBG_PRINT("CALayer::layoutSublayers.1: Sub[%d] %p frame %lf/%lf %lfx%lf -> %lf/%lf %lfx%lf\n", + (int)i, sub, + sFrame.origin.x, sFrame.origin.y, sFrame.size.width, sFrame.size.height, + sFrame2.origin.x, sFrame2.origin.y, sFrame2.size.width, sFrame2.size.height); + #endif + [sub setFrame: sFrame2]; + } + #ifdef VERBOSE + DBG_PRINT("CALayer::layoutSublayers.X: Root %p . Sub[%d] %p : frame r: %lf/%lf %lfx%lf . s: %lf/%lf %lfx%lf\n", + self, (int)i, sub, + rFrame.origin.x, rFrame.origin.y, rFrame.size.width, rFrame.size.height, + sFrame.origin.x, sFrame.origin.y, sFrame.size.width, sFrame.size.height); + #endif + } + } + } else { + [super layoutSublayers]; + } +} + +- (void) setFrame:(CGRect) frame +{ + if( fixedFrameSet ) { + [super setFrame: fixedFrame]; + } else { + [super setFrame: frame]; + } +} + +- (void)fixCALayerLayout: (CALayer*) subLayer x:(jint)x y:(jint)y width:(jint)width height:(jint)height caLayerQuirks:(jint)caLayerQuirks force:(jboolean) force +{ + { + CALayer* superLayer = [self superlayer]; + CGRect superFrame = [superLayer frame]; + CGRect lFrame = [self frame]; + int posQuirk = 0 != ( NW_DEDICATEDFRAME_QUIRK_POSITION & caLayerQuirks ) && ( lFrame.origin.x!=0 || lFrame.origin.y!=0 ); + int sizeQuirk = 0 != ( NW_DEDICATEDFRAME_QUIRK_SIZE & caLayerQuirks ) && ( lFrame.size.width!=width || lFrame.size.height!=height ); + if( !posQuirk ) { + // Use root layer position, sub-layer will be on 0/0, + // Given AWT position is location on screen w/o insets and top/left origin! + fixedFrame.origin.x = x; + fixedFrame.origin.y = superFrame.size.height - height - y; // AWT's position top/left -> bottom/left + posQuirk |= 8; + } else { + // Buggy super layer position, always use 0/0 + fixedFrame.origin.x = 0; + fixedFrame.origin.y = 0; + } + if( !sizeQuirk ) { + fixedFrame.size.width = lFrame.size.width; + fixedFrame.size.height = lFrame.size.height; + } else { + fixedFrame.size.width = width; + fixedFrame.size.height = height; + } + DBG_PRINT("CALayer::FixCALayerLayout0.0: Quirks [%d, pos %d, size %d], Super %p frame %lf/%lf %lfx%lf, Root %p frame %lf/%lf %lfx%lf, usr %d/%d %dx%d -> %lf/%lf %lfx%lf\n", + caLayerQuirks, posQuirk, sizeQuirk, + superLayer, superFrame.origin.x, superFrame.origin.y, superFrame.size.width, superFrame.size.height, + self, lFrame.origin.x, lFrame.origin.y, lFrame.size.width, lFrame.size.height, + x, y, width, height, fixedFrame.origin.x, fixedFrame.origin.y, fixedFrame.size.width, fixedFrame.size.height); + if( posQuirk || sizeQuirk ) { + fixedFrameSet = 1; + [super setFrame: fixedFrame]; + } + } + if( NULL != subLayer ) { + CGRect lFrame = [subLayer frame]; + int sizeQuirk = 0 != ( NW_DEDICATEDFRAME_QUIRK_SIZE & caLayerQuirks ) && ( lFrame.size.width!=width || lFrame.size.height!=height ); + CGFloat _x, _y, _w, _h; + int posQuirk = 0 != ( NW_DEDICATEDFRAME_QUIRK_POSITION & caLayerQuirks ) && ( lFrame.origin.x!=0 || lFrame.origin.y!=0 ); + // Sub rel. to used root layer + _x = 0; + _y = 0; + posQuirk |= 8; + if( !sizeQuirk ) { + _w = lFrame.size.width; + _h = lFrame.size.height; + } else { + _w = width; + _h = height; + } + DBG_PRINT("CALayer::FixCALayerLayout1.0: Quirks [%d, pos %d, size %d], SubL %p frame %lf/%lf %lfx%lf, usr %dx%d -> %lf/%lf %lfx%lf\n", + caLayerQuirks, posQuirk, sizeQuirk, subLayer, lFrame.origin.x, lFrame.origin.y, lFrame.size.width, lFrame.size.height, + width, height, _x, _y, _w, _h); + if( force || posQuirk || sizeQuirk ) { + lFrame.origin.x = _x; + lFrame.origin.y = _y; + lFrame.size.width = _w; + lFrame.size.height = _h; + if( [subLayer conformsToProtocol:@protocol(NWDedicatedFrame)] ) { + CALayer <NWDedicatedFrame> * subLayerDS = (CALayer <NWDedicatedFrame> *) subLayer; + [subLayerDS setDedicatedFrame: lFrame quirks: caLayerQuirks]; + } else { + [subLayer setFrame: lFrame]; + } + } + } +} + @end /* @@ -409,98 +538,32 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateCALayer0 if(0 == height) { height = 32; } // initial dummy size ! - CGRect lRect = [layer frame]; - lRect.origin.x = 0; - lRect.origin.y = 0; - lRect.size.width = width; - lRect.size.height = height; - [layer setFrame: lRect]; + CGRect lFrame = [layer frame]; + lFrame.origin.x = 0; + lFrame.origin.y = 0; + lFrame.size.width = width; + lFrame.size.height = height; + [layer setFrame: lFrame]; // no animations for add/remove/swap sublayers etc // doesn't work: [layer removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition] [layer removeAllAnimations]; // [layer addAnimation:nil forKey:kCATransition]; [layer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)]; [layer setNeedsDisplayOnBoundsChange: YES]; - DBG_PRINT("CALayer::CreateCALayer.1: root %p %lf/%lf %lfx%lf\n", layer, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height); + DBG_PRINT("CALayer::CreateCALayer.1: root %p %lf/%lf %lfx%lf\n", layer, lFrame.origin.x, lFrame.origin.y, lFrame.size.width, lFrame.size.height); [pool release]; DBG_PRINT("CALayer::CreateCALayer.X: root %p (refcnt %d)\n", layer, (int)[layer retainCount]); return (jlong) ((intptr_t) layer); } -static void FixCALayerLayout0(MyCALayer* rootLayer, CALayer* subLayer, jint width, jint height, jint caLayerQuirks, jboolean force) { - if( NULL != rootLayer ) { - CGRect lRect = [rootLayer frame]; - int posQuirk = 0 != ( NW_DEDICATEDFRAME_QUIRK_POSITION & caLayerQuirks ) && ( lRect.origin.x!=0 || lRect.origin.y!=0 ); - int sizeQuirk = 0 != ( NW_DEDICATEDFRAME_QUIRK_SIZE & caLayerQuirks ) && ( lRect.size.width!=width || lRect.size.height!=height ); - CGFloat _x, _y, _w, _h; - // force root -> 0/0 - _x = 0; - _y = 0; - posQuirk |= 8; - if( sizeQuirk ) { - _w = width; - _h = height; - } else { - _w = lRect.size.width; - _h = lRect.size.height; - } - DBG_PRINT("CALayer::FixCALayerLayout0.0: Quirks [%d, pos %d, size %d], Root %p frame %lf/%lf %lfx%lf, usr %dx%d -> %lf/%lf %lfx%lf\n", - caLayerQuirks, posQuirk, sizeQuirk, rootLayer, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, - width, height, _x, _y, _w, _h); - if( posQuirk || sizeQuirk ) { - lRect.origin.x = _x; - lRect.origin.y = _y; - lRect.size.width = _w; - lRect.size.height = _h; - [rootLayer setFrame: lRect]; - } - } - if( NULL != subLayer ) { - CGRect lRect = [subLayer frame]; - int sizeQuirk = 0 != ( NW_DEDICATEDFRAME_QUIRK_SIZE & caLayerQuirks ) && ( lRect.size.width!=width || lRect.size.height!=height ); - CGFloat _x, _y, _w, _h; - int posQuirk = 0 != ( NW_DEDICATEDFRAME_QUIRK_POSITION & caLayerQuirks ) && ( lRect.origin.x!=0 || lRect.origin.y!=0 ); - if( posQuirk ) { - _x = 0; - _y = 0; - } else { - // sub always rel to root - _x = lRect.origin.x; - _y = lRect.origin.y; - } - if( sizeQuirk ) { - _w = width; - _h = height; - } else { - _w = lRect.size.width; - _h = lRect.size.height; - } - DBG_PRINT("CALayer::FixCALayerLayout1.0: Quirks [%d, pos %d, size %d], SubL %p frame %lf/%lf %lfx%lf, usr %dx%d -> %lf/%lf %lfx%lf\n", - caLayerQuirks, posQuirk, sizeQuirk, subLayer, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, - width, height, _x, _y, _w, _h); - if( force || posQuirk || sizeQuirk ) { - lRect.origin.x = _x; - lRect.origin.y = _y; - lRect.size.width = _w; - lRect.size.height = _h; - if( [subLayer conformsToProtocol:@protocol(NWDedicatedFrame)] ) { - CALayer <NWDedicatedFrame> * subLayerDS = (CALayer <NWDedicatedFrame> *) subLayer; - [subLayerDS setDedicatedFrame: lRect quirks: caLayerQuirks]; - } else { - [subLayer setFrame: lRect]; - } - } - } -} - /* * Class: Java_jogamp_nativewindow_macosx_OSXUtil * Method: AddCASublayer0 * Signature: (JJIIIII)V */ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_AddCASublayer0 - (JNIEnv *env, jclass unused, jlong rootCALayer, jlong subCALayer, jint width, jint height, jint caLayerQuirks) + (JNIEnv *env, jclass unused, jlong rootCALayer, jlong subCALayer, jint x, jint y, jint width, jint height, jint caLayerQuirks) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; MyCALayer* rootLayer = (MyCALayer*) ((intptr_t) rootCALayer); @@ -513,23 +576,10 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_AddCASublayer0 [subLayer retain]; // Pairs w/ RemoveCASublayer CGRect lRectRoot = [rootLayer frame]; - int posQuirk = 0 != ( NW_DEDICATEDFRAME_QUIRK_POSITION & caLayerQuirks ); - int sizeQuirk = 0 != ( NW_DEDICATEDFRAME_QUIRK_SIZE & caLayerQuirks ); - - DBG_PRINT("CALayer::AddCASublayer0.0: Quirks [%d, pos %d, size %d], Root %p (refcnt %d), Sub %p (refcnt %d), frame0: %lf/%lf %lfx%lf\n", - caLayerQuirks, posQuirk, sizeQuirk, rootLayer, (int)[rootLayer retainCount], subLayer, (int)[subLayer retainCount], + DBG_PRINT("CALayer::AddCASublayer0.0: Quirks %d, Root %p (refcnt %d), Sub %p (refcnt %d), frame0: %lf/%lf %lfx%lf\n", + caLayerQuirks, rootLayer, (int)[rootLayer retainCount], subLayer, (int)[subLayer retainCount], lRectRoot.origin.x, lRectRoot.origin.y, lRectRoot.size.width, lRectRoot.size.height); - CGPoint origin = lRectRoot.origin; // save - // force root to 0/0 - lRectRoot.origin.x = 0; - lRectRoot.origin.y = 0; - [rootLayer setFrame: lRectRoot]; - - // simple 1:1 layout rel. to root-layer ! - if( !posQuirk ) { - lRectRoot.origin = origin; - } [subLayer setFrame:lRectRoot]; [rootLayer addSublayer:subLayer]; @@ -545,7 +595,7 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_AddCASublayer0 [subLayer setNeedsDisplayOnBoundsChange: YES]; if( 0 != caLayerQuirks ) { - FixCALayerLayout0(rootLayer, subLayer, width, height, caLayerQuirks, JNI_TRUE); + [rootLayer fixCALayerLayout: subLayer x:x y:y width:width height:height caLayerQuirks:caLayerQuirks force:JNI_TRUE]; } [CATransaction commit]; @@ -561,17 +611,20 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_AddCASublayer0 * Signature: (JJIII)V */ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_FixCALayerLayout0 - (JNIEnv *env, jclass unused, jlong rootCALayer, jlong subCALayer, jint width, jint height, jint caLayerQuirks) + (JNIEnv *env, jclass unused, jlong rootCALayer, jlong subCALayer, jint x, jint y, jint width, jint height, jint caLayerQuirks) { if( 0 != caLayerQuirks ) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; MyCALayer* rootLayer = (MyCALayer*) ((intptr_t) rootCALayer); + if( NULL == rootLayer ) { + NativewindowCommon_throwNewRuntimeException(env, "Argument \"rootLayer\" is null"); + } CALayer* subLayer = (CALayer*) ((intptr_t) subCALayer); [CATransaction begin]; [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; - FixCALayerLayout0(rootLayer, subLayer, width, height, caLayerQuirks, JNI_FALSE); + [rootLayer fixCALayerLayout: subLayer x:x y:y width:width height:height caLayerQuirks:caLayerQuirks force:JNI_FALSE]; [CATransaction commit]; diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPosAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPosAWT.java index 48340aa75..358e97622 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPosAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug816OSXCALayerPosAWT.java @@ -33,8 +33,13 @@ import javax.media.opengl.*; import com.jogamp.opengl.util.Animator; import javax.media.opengl.awt.GLCanvas; +import javax.swing.BoundedRangeModel; import javax.swing.BoxLayout; import javax.swing.JFrame; +import javax.swing.JScrollBar; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.ScrollPaneConstants; import com.jogamp.common.util.awt.AWTEDTExecutor; import com.jogamp.newt.event.awt.AWTWindowAdapter; @@ -68,9 +73,15 @@ import org.junit.Test; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; +/** + * Bug 816: OSX CALayer Positioning Bug. + * <p> + * Diff. OSX CALayer positioning w/ java6, [7uxx..7u40[, and >= 7u40 + * </p> + */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class TestBug816OSXCALayerPosAWT extends UITestCase { - public enum FrameLayout { None, Flow, DoubleBorderCenterSurrounded, Box }; + public enum FrameLayout { None, Flow, DoubleBorderCenterSurrounded, Box, Split }; static long duration = 1600; // ms static int width, height; @@ -113,7 +124,7 @@ public class TestBug816OSXCALayerPosAWT extends UITestCase { comp2.setPreferredSize(new_sz2); comp2.setSize(new_sz2); } - if( null != frame ) { + if( null != frame ) { frame.pack(); } } } ); @@ -206,6 +217,39 @@ public class TestBug816OSXCALayerPosAWT extends UITestCase { framePane.add(c); } break; + case Split: { + Dimension sbDim = new Dimension(16, 16); + JScrollPane vsp = new JScrollPane(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + { + JScrollBar vsb = vsp.getVerticalScrollBar(); + vsb.setPreferredSize(sbDim); + BoundedRangeModel model = vsb.getModel(); + model.setMinimum(0); + model.setMaximum(100); + model.setValue(50); + model.setExtent(1); + vsb.setEnabled(true); + } + JScrollPane hsp = new JScrollPane(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); + { + JScrollBar hsb = hsp.getHorizontalScrollBar(); + hsb.setPreferredSize(sbDim); + BoundedRangeModel model = hsb.getModel(); + model.setMinimum(0); + model.setMaximum(100); + model.setValue(50); + model.setExtent(1); + hsb.setEnabled(true); + } + JSplitPane horizontalSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, + twoCanvas ? glCanvas2 : vsp, glCanvas1 ); + horizontalSplitPane.setResizeWeight(0.5); + JSplitPane verticalSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, + true, horizontalSplitPane, hsp); + verticalSplitPane.setResizeWeight(0.5); + framePane.add(verticalSplitPane); + } + break; } final GearsES2 demo1 = new GearsES2(swapInterval); glCanvas1.addGLEventListener(demo1); @@ -329,27 +373,41 @@ public class TestBug816OSXCALayerPosAWT extends UITestCase { } @Test - public void test04_Compo_Flow_Two() throws InterruptedException, InvocationTargetException { + public void test04_Compo_Split_One() throws InterruptedException, InvocationTargetException { if( testNum != -1 && testNum != 4 ) { return ; } final GLCapabilities caps = new GLCapabilities(getGLP()); + runTestGL(caps, FrameLayout.Split, false /* twoCanvas */, true /* resizeByComp */); + } + + @Test + public void test05_Compo_Flow_Two() throws InterruptedException, InvocationTargetException { + if( testNum != -1 && testNum != 5 ) { return ; } + final GLCapabilities caps = new GLCapabilities(getGLP()); runTestGL(caps, FrameLayout.Flow, true/* twoCanvas */, true /* resizeByComp */); } @Test - public void test05_Compo_DblBrd_Two() throws InterruptedException, InvocationTargetException { - if( testNum != -1 && testNum != 5 ) { return ; } + public void test06_Compo_DblBrd_Two() throws InterruptedException, InvocationTargetException { + if( testNum != -1 && testNum != 6 ) { return ; } final GLCapabilities caps = new GLCapabilities(getGLP()); runTestGL(caps, FrameLayout.DoubleBorderCenterSurrounded, true/* twoCanvas */, true /* resizeByComp */); } @Test - public void test06_Compo_Box_Two() throws InterruptedException, InvocationTargetException { - if( testNum != -1 && testNum != 6 ) { return ; } + public void test07_Compo_Box_Two() throws InterruptedException, InvocationTargetException { + if( testNum != -1 && testNum != 7 ) { return ; } final GLCapabilities caps = new GLCapabilities(getGLP()); runTestGL(caps, FrameLayout.Box, true/* twoCanvas */, true /* resizeByComp */); } @Test + public void test08_Compo_Split_Two() throws InterruptedException, InvocationTargetException { + if( testNum != -1 && testNum != 8 ) { return ; } + final GLCapabilities caps = new GLCapabilities(getGLP()); + runTestGL(caps, FrameLayout.Split, true/* twoCanvas */, true /* resizeByComp */); + } + + @Test public void test10_Frame_None_One() throws InterruptedException, InvocationTargetException { if( testNum != -1 && testNum != 10 ) { return ; } final GLCapabilities caps = new GLCapabilities(getGLP()); @@ -378,26 +436,40 @@ public class TestBug816OSXCALayerPosAWT extends UITestCase { } @Test - public void test14_Frame_Flow_Two() throws InterruptedException, InvocationTargetException { - if( testNum != -1 && testNum != 14 ) { return ; } + public void test14_Frame_Split_One() throws InterruptedException, InvocationTargetException { + if( testNum != -1 && testNum != 14) { return ; } + final GLCapabilities caps = new GLCapabilities(getGLP()); + runTestGL(caps, FrameLayout.Split, false /* twoCanvas */, false /* resizeByComp */); + } + + @Test + public void test15_Frame_Flow_Two() throws InterruptedException, InvocationTargetException { + if( testNum != -1 && testNum != 15 ) { return ; } final GLCapabilities caps = new GLCapabilities(getGLP()); runTestGL(caps, FrameLayout.Flow, true/* twoCanvas */, false /* resizeByComp */); } @Test - public void test15_Frame_DblBrd_Two() throws InterruptedException, InvocationTargetException { - if( testNum != -1 && testNum != 15 ) { return ; } + public void test16_Frame_DblBrd_Two() throws InterruptedException, InvocationTargetException { + if( testNum != -1 && testNum != 16 ) { return ; } final GLCapabilities caps = new GLCapabilities(getGLP()); runTestGL(caps, FrameLayout.DoubleBorderCenterSurrounded, true/* twoCanvas */, false /* resizeByComp */); } @Test - public void test16_Frame_Box_Two() throws InterruptedException, InvocationTargetException { - if( testNum != -1 && testNum != 16 ) { return ; } + public void test17_Frame_Box_Two() throws InterruptedException, InvocationTargetException { + if( testNum != -1 && testNum != 17 ) { return ; } final GLCapabilities caps = new GLCapabilities(getGLP()); runTestGL(caps, FrameLayout.Box, true/* twoCanvas */, false /* resizeByComp */); } + @Test + public void test18_Frame_Split_Two() throws InterruptedException, InvocationTargetException { + if( testNum != -1 && testNum != 18 ) { return ; } + final GLCapabilities caps = new GLCapabilities(getGLP()); + runTestGL(caps, FrameLayout.Split, true/* twoCanvas */, false /* resizeByComp */); + } + static int testNum = -1; public static void main(String args[]) { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/Bug816AppletGLCanvas01.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/Bug816AppletGLCanvas01.java new file mode 100644 index 000000000..175b053d1 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/Bug816AppletGLCanvas01.java @@ -0,0 +1,134 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.test.junit.jogl.demos.es2.awt; + +import java.applet.Applet; +import java.awt.Color; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import javax.media.opengl.GL; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLEventListener; +import javax.media.opengl.GLProfile; +import javax.media.opengl.awt.GLCanvas; +import javax.swing.JFrame; +import javax.swing.JPanel; + +/** + * Bug 816: OSX CALayer Positioning Bug. + * <p> + * Diff. OSX CALayer positioning w/ java6, [7uxx..7u40[, and >= 7u40 + * </p> + * <p> + * Test simply positions a GLCanvas via setBounds(..) within it's Applet. + * </p> + */ +@SuppressWarnings("serial") +public class Bug816AppletGLCanvas01 extends Applet implements GLEventListener { + + public Bug816AppletGLCanvas01() { + } + + public static JFrame frame; + public static JPanel appletHolder; + public static boolean isApplet = true; + + static public void main(String args[]) { + Applet myApplet = null; + isApplet = false; + + myApplet = new Bug816AppletGLCanvas01(); + appletStarter(myApplet, "Bug861AppletGLCanvasTest01", 800, 600); + } + + static public void appletStarter(final Applet des, String frameName, int width, int height) { + appletHolder = new JPanel(); + if (frame != null) { + frame.dispose(); + frame = null; + } + frame = new JFrame(frameName); + frame.setVisible(false); + frame.getContentPane().add(appletHolder); + + appletHolder.setLayout(null); + des.setBounds(0, 0, width, height); + appletHolder.add(des); + + frame.setVisible(true); + int frameBorderSize = appletHolder.getLocationOnScreen().x - frame.getLocationOnScreen().x; + int titleBarHeight = appletHolder.getLocationOnScreen().y - frame.getLocationOnScreen().y; + int frameWidth = width + 2 * frameBorderSize; + int frameHeight = height + titleBarHeight + frameBorderSize; + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(frameWidth, frameHeight); + frame.setVisible(true); + des.init(); + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + } + + public void init() { + initOpenGLAWT(); + } + + public void initOpenGLAWT() { + setBackground(Color.gray); + setLayout(null); + + GLProfile glp = GLProfile.getDefault(); + GLCapabilities caps = new GLCapabilities(glp); + GLCanvas canvas = new GLCanvas((GLCapabilitiesImmutable) caps); + canvas.setBounds(50, 50, 200, 450); + canvas.addGLEventListener(this); + add(canvas); + } + + public void init(GLAutoDrawable gLAutoDrawable) { + GL gl = gLAutoDrawable.getGL(); + gl.glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + gl.glClear(GL.GL_COLOR_BUFFER_BIT); + gLAutoDrawable.swapBuffers(); + } + + public void dispose(GLAutoDrawable glad) { + } + + public void display(GLAutoDrawable glad) { + } + + public void reshape(GLAutoDrawable glad, int i, int i1, int i2, int i3) { + } + +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/Bug816AppletGLCanvas02.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/Bug816AppletGLCanvas02.java new file mode 100644 index 000000000..9ae0a2bbd --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/Bug816AppletGLCanvas02.java @@ -0,0 +1,85 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.test.junit.jogl.demos.es2.awt; + +import java.applet.Applet; +import java.util.ArrayList; +import java.util.List; + +import javax.media.opengl.GLAnimatorControl; +import javax.media.opengl.awt.GLCanvas; +import javax.swing.BoxLayout; + +import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; +import com.jogamp.opengl.util.Animator; + +/** + * Bug 816: OSX CALayer Positioning Bug. + * <p> + * Diff. OSX CALayer positioning w/ java6, [7uxx..7u40[, and >= 7u40 + * </p> + * <p> + * Test uses a box layout within the Applet. + * </p> + */ +@SuppressWarnings("serial") +public class Bug816AppletGLCanvas02 extends Applet { + private List<GLAnimatorControl> animators = new ArrayList<GLAnimatorControl>(2); + + @Override + public void init() { + System.err.println("GearsApplet: init() - begin"); + new BoxLayout(this, BoxLayout.X_AXIS); + setSize(600, 300); + add(createCanvas()); + add(createCanvas()); + System.err.println("GearsApplet: init() - end"); + } + + private GLCanvas createCanvas() { + GLCanvas canvas = new GLCanvas(); + canvas.addGLEventListener(new GearsES2(1)); + canvas.setSize(300, 300); + animators.add(new Animator(canvas)); + return canvas; + } + + @Override + public void start() { + for (GLAnimatorControl control : animators) { + control.start(); + } + } + + @Override + public void stop() { + for (GLAnimatorControl control : animators) { + control.stop(); + } + } +} |