summaryrefslogtreecommitdiffstats
path: root/src/newt
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2010-12-19 14:54:08 +0100
committerSven Gothel <[email protected]>2010-12-19 14:54:08 +0100
commit2cbab63bd6c230d31b8ae6f1d794ad49bf23bb53 (patch)
tree9da105f466b81424ae089e59e4bd67fce7c32d54 /src/newt
parent2323c30c23b6f9eb7d7ccf94e6cdcbcb3d2f34a6 (diff)
JOGL/NEWT: Introduce WindowClosingProtocol (solves Bug/Request 444)
Similar to JFrame's closing behavior, the following components window closing follow the new WindowClosingProtocol: - GLCanvas - GLJPanel - NEWT Window, GLWindow - NEWT NewtCanvasAWT The implementation obeys either 1) the user value set by this interface, 2) an underlying toolkit set user value (JFrame, ..) 3) or it's default, eg. {@link #DO_NOTHING_ON_CLOSE DO_NOTHING_ON_CLOSE} within an AWT environment. If none of the above determines the operation, this protocol default behavior {@link #DISPOSE_ON_CLOSE DISPOSE_ON_CLOSE} shall be used.
Diffstat (limited to 'src/newt')
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java3
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java78
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/WindowImpl.java22
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java47
4 files changed, 110 insertions, 40 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index 99db47168..9fe5089be 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -36,13 +36,14 @@ import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.util.Insets;
/**
* Specifying the public Window functionality for the
* using a Window and for shadowing one like {@link com.jogamp.newt.opengl.GLWindow}.
*/
-public interface Window extends NativeWindow {
+public interface Window extends NativeWindow, WindowClosingProtocol {
public static final boolean DEBUG_MOUSE_EVENT = Debug.debug("Window.MouseEvent");
public static final boolean DEBUG_KEY_EVENT = Debug.debug("Window.KeyEvent");
public static final boolean DEBUG_WINDOW_EVENT = Debug.debug("Window.WindowEvent");
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index bee81624a..18213f94f 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -38,21 +38,36 @@ import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.KeyboardFocusManager;
-import javax.media.nativewindow.*;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.WindowClosingProtocol;
+import javax.media.nativewindow.awt.AWTWindowClosingProtocol;
+import com.jogamp.nativewindow.impl.awt.AWTMisc;
import com.jogamp.newt.event.awt.AWTAdapter;
import com.jogamp.newt.event.awt.AWTParentWindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.Window;
+import com.jogamp.newt.event.WindowAdapter;
+import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.impl.Debug;
+import javax.swing.MenuSelectionManager;
-public class NewtCanvasAWT extends java.awt.Canvas {
+public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProtocol {
public static final boolean DEBUG = Debug.debug("Window");
NativeWindow nativeWindow = null;
Window newtChild = null;
+ int newtChildCloseOp;
AWTAdapter awtAdapter = null;
+ private AWTWindowClosingProtocol awtWindowClosingProtocol =
+ new AWTWindowClosingProtocol(this, new Runnable() {
+ public void run() {
+ NewtCanvasAWT.this.destroy();
+ }
+ });
+
/**
* Instantiates a NewtCanvas without a NEWT child.<br>
*/
@@ -97,12 +112,18 @@ public class NewtCanvasAWT extends java.awt.Canvas {
}
FocusAction focusAction = new FocusAction();
+ WindowListener clearAWTMenusOnNewtFocus = new WindowAdapter() {
+ public void windowGainedFocus(WindowEvent arg0) {
+ MenuSelectionManager.defaultManager().clearSelectedPath();
+ }
+ };
+
/** sets a new NEWT child, provoking reparenting on the NEWT level. */
public NewtCanvasAWT setNEWTChild(Window child) {
if(newtChild!=child) {
newtChild = child;
if(null!=nativeWindow) {
- java.awt.Container cont = getContainer(this);
+ java.awt.Container cont = AWTMisc.getContainer(this);
// reparent right away, addNotify has been called already
reparentWindow( (null!=newtChild) ? true : false, cont );
}
@@ -119,24 +140,37 @@ public class NewtCanvasAWT extends java.awt.Canvas {
* or {@link #addNotify()} hasn't been called yet.*/
public NativeWindow getNativeWindow() { return nativeWindow; }
- void setWindowAdapter(boolean attach) {
+ public int getDefaultCloseOperation() {
+ return awtWindowClosingProtocol.getDefaultCloseOperation();
+ }
+
+ public int setDefaultCloseOperation(int op) {
+ return awtWindowClosingProtocol.setDefaultCloseOperation(op);
+ }
+
+ void configureNewtChild(boolean attach) {
if(null!=awtAdapter) {
awtAdapter.removeFrom(this);
awtAdapter=null;
}
- if(attach && null!=newtChild) {
- awtAdapter = new AWTParentWindowAdapter(newtChild).addTo(this);
- }
- }
-
- static java.awt.Container getContainer(java.awt.Component comp) {
- while( null != comp ) {
- if( comp instanceof java.awt.Container ) {
- return (java.awt.Container) comp;
+ if( null != newtChild ) {
+ if(attach) {
+ awtAdapter = new AWTParentWindowAdapter(newtChild).addTo(this);
+ if(newtChild.isValid()) {
+ newtChild.addWindowListener(clearAWTMenusOnNewtFocus);
+ }
+ newtChild.setFocusAction(focusAction); // enable AWT focus traversal
+ newtChildCloseOp = newtChild.setDefaultCloseOperation(WindowClosingProtocol.DO_NOTHING_ON_CLOSE);
+ awtWindowClosingProtocol.addClosingListenerOneShot();
+ } else {
+ if(newtChild.isValid()) {
+ newtChild.removeWindowListener(clearAWTMenusOnNewtFocus);
+ }
+ newtChild.setFocusAction(null);
+ newtChild.setDefaultCloseOperation(newtChildCloseOp);
+ awtWindowClosingProtocol.removeClosingListener();
}
- comp = comp.getParent();
}
- return null;
}
public void addNotify() {
@@ -150,7 +184,7 @@ public class NewtCanvasAWT extends java.awt.Canvas {
// after native peer is valid: Windows
disableBackgroundErase();
- java.awt.Container cont = getContainer(this);
+ java.awt.Container cont = AWTMisc.getContainer(this);
if(DEBUG) {
// if ( isShowing() == false ) -> Container was not visible yet.
// if ( isShowing() == true ) -> Container is already visible.
@@ -161,7 +195,7 @@ public class NewtCanvasAWT extends java.awt.Canvas {
}
public void removeNotify() {
- java.awt.Container cont = getContainer(this);
+ java.awt.Container cont = AWTMisc.getContainer(this);
if(DEBUG) {
System.err.println("NewtCanvasAWT.removeNotify: "+newtChild+", from "+cont);
}
@@ -187,13 +221,12 @@ public class NewtCanvasAWT extends java.awt.Canvas {
newtChild.setSize(w, h);
newtChild.reparentWindow(nativeWindow);
newtChild.setVisible(true);
- setWindowAdapter(true);
+ configureNewtChild(true);
newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
newtChild.windowRepaint(0, 0, w, h);
- newtChild.setFocusAction(focusAction); // enable AWT focus traversal
}
} else {
- setWindowAdapter(false);
+ configureNewtChild(false);
nativeWindow = null;
newtChild.setVisible(false);
newtChild.reparentWindow(null);
@@ -213,10 +246,11 @@ public class NewtCanvasAWT extends java.awt.Canvas {
*/
public final void destroy() {
if(null!=newtChild) {
- java.awt.Container cont = getContainer(this);
+ java.awt.Container cont = AWTMisc.getContainer(this);
if(DEBUG) {
System.err.println("NewtCanvasAWT.destroy(): "+newtChild+", from "+cont);
}
+ configureNewtChild(false);
nativeWindow = null;
newtChild.setVisible(false);
newtChild.reparentWindow(null);
@@ -229,11 +263,13 @@ public class NewtCanvasAWT extends java.awt.Canvas {
}
public void paint(Graphics g) {
+ awtWindowClosingProtocol.addClosingListenerOneShot();
if(null!=newtChild) {
newtChild.windowRepaint(0, 0, getWidth(), getHeight());
}
}
public void update(Graphics g) {
+ awtWindowClosingProtocol.addClosingListenerOneShot();
if(null!=newtChild) {
newtChild.windowRepaint(0, 0, getWidth(), getHeight());
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java
index ad11d8ab9..e04bd1208 100644
--- a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java
+++ b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java
@@ -372,6 +372,26 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
protected void unlockSurfaceImpl() { }
//----------------------------------------------------------------------
+ // WindowClosingProtocol implementation
+ //
+ private Object closingListenerLock = new Object();
+ private int defaultCloseOperation = DISPOSE_ON_CLOSE;
+
+ public int getDefaultCloseOperation() {
+ synchronized (closingListenerLock) {
+ return defaultCloseOperation;
+ }
+ }
+
+ public int setDefaultCloseOperation(int op) {
+ synchronized (closingListenerLock) {
+ int _op = defaultCloseOperation;
+ defaultCloseOperation = op;
+ return _op;
+ }
+ }
+
+ //----------------------------------------------------------------------
// Window: Native implementation
//
@@ -2101,7 +2121,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
- if(handleDestroyNotify && isValid()) {
+ if(handleDestroyNotify && DISPOSE_ON_CLOSE == defaultCloseOperation && isValid()) {
destroy();
}
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 358a3d4ce..4a1855d05 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -85,24 +85,26 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
}
public void windowDestroyNotify(WindowEvent e) {
- // Is an animator thread perform rendering?
- if (GLWindow.this.helper.isExternalAnimatorRunning()) {
- // Pause animations before initiating safe destroy.
- GLAnimatorControl ctrl = GLWindow.this.helper.getAnimator();
- boolean isPaused = ctrl.pause();
- destroy();
- if(isPaused) {
- ctrl.resume();
+ if( DISPOSE_ON_CLOSE == GLWindow.this.getDefaultCloseOperation() ) {
+ // Is an animator thread perform rendering?
+ if (GLWindow.this.helper.isExternalAnimatorRunning()) {
+ // Pause animations before initiating safe destroy.
+ GLAnimatorControl ctrl = GLWindow.this.helper.getAnimator();
+ boolean isPaused = ctrl.pause();
+ destroy();
+ if(isPaused) {
+ ctrl.resume();
+ }
+ } else if (GLWindow.this.window.isSurfaceLockedByOtherThread()) {
+ // Surface is locked by another thread
+ // Flag that destroy should be performed on the next
+ // attempt to display.
+ sendDestroy = true;
+ } else {
+ // Without an external thread animating or locking the
+ // surface, we are safe.
+ destroy ();
}
- } else if (GLWindow.this.window.isSurfaceLockedByOtherThread()) {
- // Surface is locked by another thread
- // Flag that destroy should be performed on the next
- // attempt to display.
- sendDestroy = true;
- } else {
- // Without an external thread animating or locking the
- // surface, we are safe.
- destroy ();
}
}
});
@@ -152,6 +154,17 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
}
//----------------------------------------------------------------------
+ // WindowClosingProtocol implementation
+ //
+ public int getDefaultCloseOperation() {
+ return window.getDefaultCloseOperation();
+ }
+
+ public int setDefaultCloseOperation(int op) {
+ return window.setDefaultCloseOperation(op);
+ }
+
+ //----------------------------------------------------------------------
// Window Access
//