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 jogamp.newt.awt.event;
30 
31 import java.awt.KeyboardFocusManager;
32 
33 import com.jogamp.nativewindow.NativeWindow;
34 
35 import jogamp.newt.driver.DriverUpdatePosition;
36 
37 import com.jogamp.newt.Window;
38 import com.jogamp.newt.event.awt.AWTAdapter;
39 import com.jogamp.newt.event.awt.AWTWindowAdapter;
40 
41 /**
42  * Specialized parent/client adapter,
43  * where the NEWT child window really gets resized,
44  * and the parent move window event gets discarded. */
45 public class AWTParentWindowAdapter extends AWTWindowAdapter implements java.awt.event.HierarchyListener
46 {
47     NativeWindow downstreamParent;
48 
AWTParentWindowAdapter(final NativeWindow downstreamParent, final com.jogamp.newt.Window downstream)49     public AWTParentWindowAdapter(final NativeWindow downstreamParent, final com.jogamp.newt.Window downstream) {
50         super(downstream);
51         this.downstreamParent = downstreamParent;
52     }
AWTParentWindowAdapter()53     public AWTParentWindowAdapter() {
54         super();
55     }
setDownstream(final NativeWindow downstreamParent, final com.jogamp.newt.Window downstream)56     public AWTParentWindowAdapter setDownstream(final NativeWindow downstreamParent, final com.jogamp.newt.Window downstream) {
57         setDownstream(downstream);
58         this.downstreamParent = downstreamParent;
59         return this;
60     }
61 
62     @Override
clear()63     public synchronized AWTAdapter clear() {
64         super.clear();
65         this.downstreamParent = null;
66         return this;
67     }
68 
69     @Override
addTo(final java.awt.Component awtComponent)70     public synchronized AWTAdapter addTo(final java.awt.Component awtComponent) {
71         awtComponent.addHierarchyListener(this);
72         return super.addTo(awtComponent);
73     }
74 
75     @Override
removeFrom(final java.awt.Component awtComponent)76     public synchronized AWTAdapter removeFrom(final java.awt.Component awtComponent) {
77         awtComponent.removeHierarchyListener(this);
78         return super.removeFrom(awtComponent);
79     }
80 
81     @Override
focusGained(final java.awt.event.FocusEvent e)82     public synchronized void focusGained(final java.awt.event.FocusEvent e) {
83         if( !isSetup ) { return; }
84         // forward focus to NEWT child
85         final com.jogamp.newt.Window newtChild = getNewtWindow();
86         if( null != newtChild ) {
87             final boolean isOnscreen = newtChild.isNativeValid() && newtChild.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
88             final boolean isParent = downstreamParent == newtChild.getParent();
89             final boolean isFullscreen = newtChild.isFullscreen();
90             if(DEBUG_IMPLEMENTATION) {
91                 System.err.println("AWT: focusGained: onscreen "+ isOnscreen+", "+e+", isParent: "+isParent+", isFS "+isFullscreen);
92             }
93             if(isParent) {
94                 if(isOnscreen && !isFullscreen) {
95                     KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
96                 }
97                 newtChild.requestFocus(false);
98             }
99         }
100     }
101 
102     @Override
focusLost(final java.awt.event.FocusEvent e)103     public synchronized void focusLost(final java.awt.event.FocusEvent e) {
104         if( !isSetup ) { return; }
105         if(DEBUG_IMPLEMENTATION) {
106             System.err.println("AWT: focusLost: "+ e);
107         }
108     }
109 
110     @Override
componentResized(final java.awt.event.ComponentEvent e)111     public synchronized void componentResized(final java.awt.event.ComponentEvent e) {
112         if( !isSetup ) { return; }
113         // Need to resize the NEWT child window
114         // the resized event will be send via the native window feedback.
115         final java.awt.Component comp = e.getComponent();
116         if(DEBUG_IMPLEMENTATION) {
117             System.err.println("AWT: componentResized: "+comp);
118         }
119         final Window newtChild = getNewtWindow();
120         if( null != newtChild ) {
121             newtChild.runOnEDTIfAvail(false, new Runnable() {
122                 @Override
123                 public void run() {
124                     final int cw = comp.getWidth();
125                     final int ch = comp.getHeight();
126                     if( 0 < cw && 0 < ch ) {
127                         if( newtChild.getWidth() != cw || newtChild.getHeight() != ch ) {
128                             newtChild.setSize(cw, ch);
129                             final boolean v = comp.isShowing(); // compute showing-state throughout hierarchy
130                             if(v != newtChild.isVisible()) {
131                                 newtChild.setVisible(v);
132                             }
133                         }
134                     } else if(newtChild.isVisible()) {
135                         newtChild.setVisible(false);
136                     }
137                 }});
138         }
139     }
140 
141     @Override
componentMoved(final java.awt.event.ComponentEvent e)142     public synchronized void componentMoved(final java.awt.event.ComponentEvent e) {
143         if( !isSetup ) { return; }
144         if(DEBUG_IMPLEMENTATION) {
145             System.err.println("AWT: componentMoved: "+e);
146         }
147         final Window newtChild = getNewtWindow();
148         if( null != newtChild && ( newtChild.getDelegatedWindow() instanceof DriverUpdatePosition ) ) {
149             ((DriverUpdatePosition)newtChild.getDelegatedWindow()).updatePosition(0, 0);
150         }
151     }
152 
153     @Override
windowActivated(final java.awt.event.WindowEvent e)154     public synchronized void windowActivated(final java.awt.event.WindowEvent e) {
155         // no propagation to NEWT child window
156     }
157 
158     @Override
windowDeactivated(final java.awt.event.WindowEvent e)159     public synchronized void windowDeactivated(final java.awt.event.WindowEvent e) {
160         // no propagation to NEWT child window
161     }
162 
163     @Override
hierarchyChanged(final java.awt.event.HierarchyEvent e)164     public synchronized void hierarchyChanged(final java.awt.event.HierarchyEvent e) {
165         if( !isSetup ) { return; }
166         final Window newtChild = getNewtWindow();
167         if( null != newtChild && null == getNewtEventListener() ) {
168             final long bits = e.getChangeFlags();
169             final java.awt.Component comp = e.getComponent();
170             if( 0 != ( java.awt.event.HierarchyEvent.SHOWING_CHANGED & bits ) ) {
171                 final boolean showing = comp.isShowing(); // compute showing-state throughout hierarchy
172                 if(DEBUG_IMPLEMENTATION) {
173                     System.err.println("AWT: hierarchyChanged SHOWING_CHANGED: showing "+showing+", comp "+comp+", changed "+e.getChanged());
174                 }
175                 newtChild.runOnEDTIfAvail(false, new Runnable() {
176                     @Override
177                     public void run() {
178                         if(newtChild.isVisible() != showing) {
179                             newtChild.setVisible(showing);
180                         }
181                     }});
182             }
183             if(DEBUG_IMPLEMENTATION) {
184                 if( 0 != ( java.awt.event.HierarchyEvent.DISPLAYABILITY_CHANGED & bits ) ) {
185                     System.err.println("AWT: hierarchyChanged DISPLAYABILITY_CHANGED: "+e.getChanged());
186                 }
187             }
188         }
189     }
190 }
191 
192