Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/awt/EmbeddedFrame.java
38827 views
/*1* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.awt;2627import java.awt.*;28import java.awt.event.*;29import java.awt.image.*;30import java.awt.peer.*;31import java.beans.PropertyChangeListener;32import java.beans.PropertyChangeEvent;33import java.util.Set;34import java.awt.AWTKeyStroke;35import java.applet.Applet;36import sun.applet.AppletPanel;3738/**39* A generic container used for embedding Java components, usually applets.40* An EmbeddedFrame has two related uses:41*42* . Within a Java-based application, an EmbeddedFrame serves as a sort of43* firewall, preventing the contained components or applets from using44* getParent() to find parent components, such as menubars.45*46* . Within a C-based application, an EmbeddedFrame contains a window handle47* which was created by the application, which serves as the top-level48* Java window. EmbeddedFrames created for this purpose are passed-in a49* handle of an existing window created by the application. The window50* handle should be of the appropriate native type for a specific51* platform, as stored in the pData field of the ComponentPeer.52*53* @author Thomas Ball54*/55public abstract class EmbeddedFrame extends Frame56implements KeyEventDispatcher, PropertyChangeListener {5758private boolean isCursorAllowed = true;59private boolean supportsXEmbed = false;60private KeyboardFocusManager appletKFM;61// JDK 1.1 compatibility62private static final long serialVersionUID = 2967042741780317130L;6364/*65* The constants define focus traversal directions.66* Use them in {@code traverseIn}, {@code traverseOut} methods.67*/68protected static final boolean FORWARD = true;69protected static final boolean BACKWARD = false;7071public boolean supportsXEmbed() {72return supportsXEmbed && SunToolkit.needsXEmbed();73}7475protected EmbeddedFrame(boolean supportsXEmbed) {76this((long)0, supportsXEmbed);77}787980protected EmbeddedFrame() {81this((long)0);82}8384/**85* @deprecated This constructor will be removed in 1.586*/87@Deprecated88protected EmbeddedFrame(int handle) {89this((long)handle);90}9192protected EmbeddedFrame(long handle) {93this(handle, false);94}9596protected EmbeddedFrame(long handle, boolean supportsXEmbed) {97this.supportsXEmbed = supportsXEmbed;98registerListeners();99}100101/**102* Block introspection of a parent window by this child.103*/104public Container getParent() {105return null;106}107108/**109* Needed to track which KeyboardFocusManager is current. We want to avoid memory110* leaks, so when KFM stops being current, we remove ourselves as listeners.111*/112public void propertyChange(PropertyChangeEvent evt) {113// We don't handle any other properties. Skip it.114if (!evt.getPropertyName().equals("managingFocus")) {115return;116}117118// We only do it if it stops being current. Technically, we should119// never get an event about KFM starting being current.120if (evt.getNewValue() == Boolean.TRUE) {121return;122}123124// should be the same as appletKFM125removeTraversingOutListeners((KeyboardFocusManager)evt.getSource());126127appletKFM = KeyboardFocusManager.getCurrentKeyboardFocusManager();128if (isVisible()) {129addTraversingOutListeners(appletKFM);130}131}132133/**134* Register us as KeyEventDispatcher and property "managingFocus" listeners.135*/136private void addTraversingOutListeners(KeyboardFocusManager kfm) {137kfm.addKeyEventDispatcher(this);138kfm.addPropertyChangeListener("managingFocus", this);139}140141/**142* Deregister us as KeyEventDispatcher and property "managingFocus" listeners.143*/144private void removeTraversingOutListeners(KeyboardFocusManager kfm) {145kfm.removeKeyEventDispatcher(this);146kfm.removePropertyChangeListener("managingFocus", this);147}148149/**150* Because there may be many AppContexts, and we can't be sure where this151* EmbeddedFrame is first created or shown, we can't automatically determine152* the correct KeyboardFocusManager to attach to as KeyEventDispatcher.153* Those who want to use the functionality of traversing out of the EmbeddedFrame154* must call this method on the Applet's AppContext. After that, all the changes155* can be handled automatically, including possible replacement of156* KeyboardFocusManager.157*/158public void registerListeners() {159if (appletKFM != null) {160removeTraversingOutListeners(appletKFM);161}162appletKFM = KeyboardFocusManager.getCurrentKeyboardFocusManager();163if (isVisible()) {164addTraversingOutListeners(appletKFM);165}166}167168/**169* Needed to avoid memory leak: we register this EmbeddedFrame as a listener with170* KeyboardFocusManager of applet's AppContext. We don't want the KFM to keep171* reference to our EmbeddedFrame forever if the Frame is no longer in use, so we172* add listeners in show() and remove them in hide().173*/174@SuppressWarnings("deprecation")175public void show() {176if (appletKFM != null) {177addTraversingOutListeners(appletKFM);178}179super.show();180}181182/**183* Needed to avoid memory leak: we register this EmbeddedFrame as a listener with184* KeyboardFocusManager of applet's AppContext. We don't want the KFM to keep185* reference to our EmbeddedFrame forever if the Frame is no longer in use, so we186* add listeners in show() and remove them in hide().187*/188@SuppressWarnings("deprecation")189public void hide() {190if (appletKFM != null) {191removeTraversingOutListeners(appletKFM);192}193super.hide();194}195196/**197* Need this method to detect when the focus may have chance to leave the198* focus cycle root which is EmbeddedFrame. Mostly, the code here is copied199* from DefaultKeyboardFocusManager.processKeyEvent with some minor200* modifications.201*/202public boolean dispatchKeyEvent(KeyEvent e) {203204Container currentRoot = AWTAccessor.getKeyboardFocusManagerAccessor()205.getCurrentFocusCycleRoot();206207// if we are not in EmbeddedFrame's cycle, we should not try to leave.208if (this != currentRoot) {209return false;210}211212// KEY_TYPED events cannot be focus traversal keys213if (e.getID() == KeyEvent.KEY_TYPED) {214return false;215}216217if (!getFocusTraversalKeysEnabled() || e.isConsumed()) {218return false;219}220221AWTKeyStroke stroke = AWTKeyStroke.getAWTKeyStrokeForEvent(e);222Set<AWTKeyStroke> toTest;223Component currentFocused = e.getComponent();224225toTest = getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);226if (toTest.contains(stroke)) {227// 6581899: performance improvement for SortingFocusTraversalPolicy228Component last = getFocusTraversalPolicy().getLastComponent(this);229if (currentFocused == last || last == null) {230if (traverseOut(FORWARD)) {231e.consume();232return true;233}234}235}236237toTest = getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);238if (toTest.contains(stroke)) {239// 6581899: performance improvement for SortingFocusTraversalPolicy240Component first = getFocusTraversalPolicy().getFirstComponent(this);241if (currentFocused == first || first == null) {242if (traverseOut(BACKWARD)) {243e.consume();244return true;245}246}247}248return false;249}250251/**252* This method is called by the embedder when we should receive focus as element253* of the traversal chain. The method requests focus on:254* 1. the first Component of this EmbeddedFrame if user moves focus forward255* in the focus traversal cycle.256* 2. the last Component of this EmbeddedFrame if user moves focus backward257* in the focus traversal cycle.258*259* The direction parameter specifies which of the two mentioned cases is260* happening. Use FORWARD and BACKWARD constants defined in the EmbeddedFrame class261* to avoid confusing boolean values.262*263* A concrete implementation of this method is defined in the platform-dependent264* subclasses.265*266* @param direction FORWARD or BACKWARD267* @return true, if the EmbeddedFrame wants to get focus, false otherwise.268*/269public boolean traverseIn(boolean direction) {270Component comp = null;271272if (direction == FORWARD) {273comp = getFocusTraversalPolicy().getFirstComponent(this);274} else {275comp = getFocusTraversalPolicy().getLastComponent(this);276}277if (comp != null) {278// comp.requestFocus(); - Leads to a hung.279280AWTAccessor.getKeyboardFocusManagerAccessor().setMostRecentFocusOwner(this, comp);281synthesizeWindowActivation(true);282}283return (null != comp);284}285286/**287* This method is called from dispatchKeyEvent in the following two cases:288* 1. The focus is on the first Component of this EmbeddedFrame and we are289* about to transfer the focus backward.290* 2. The focus in on the last Component of this EmbeddedFrame and we are291* about to transfer the focus forward.292* This is needed to give the opportuity for keyboard focus to leave the293* EmbeddedFrame. Override this method, initiate focus transfer in it and294* return true if you want the focus to leave EmbeddedFrame's cycle.295* The direction parameter specifies which of the two mentioned cases is296* happening. Use FORWARD and BACKWARD constants defined in EmbeddedFrame297* to avoid confusing boolean values.298*299* @param direction FORWARD or BACKWARD300* @return true, if EmbeddedFrame wants the focus to leave it,301* false otherwise.302*/303protected boolean traverseOut(boolean direction) {304return false;305}306307/**308* Block modifying any frame attributes, since they aren't applicable309* for EmbeddedFrames.310*/311public void setTitle(String title) {}312public void setIconImage(Image image) {}313public void setIconImages(java.util.List<? extends Image> icons) {}314public void setMenuBar(MenuBar mb) {}315public void setResizable(boolean resizable) {}316public void remove(MenuComponent m) {}317318public boolean isResizable() {319return true;320}321322@SuppressWarnings("deprecation")323public void addNotify() {324synchronized (getTreeLock()) {325if (getPeer() == null) {326setPeer(new NullEmbeddedFramePeer());327}328super.addNotify();329}330}331332// These three functions consitute RFE 4100710. Do not remove.333@SuppressWarnings("deprecation")334public void setCursorAllowed(boolean isCursorAllowed) {335this.isCursorAllowed = isCursorAllowed;336getPeer().updateCursorImmediately();337}338public boolean isCursorAllowed() {339return isCursorAllowed;340}341public Cursor getCursor() {342return (isCursorAllowed)343? super.getCursor()344: Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);345}346347@SuppressWarnings("deprecation")348protected void setPeer(final ComponentPeer p){349AWTAccessor.getComponentAccessor().setPeer(EmbeddedFrame.this, p);350};351352/**353* Synthesize native message to activate or deactivate EmbeddedFrame window354* depending on the value of parameter <code>b</code>.355* Peers should override this method if they are to implement356* this functionality.357* @param doActivate if <code>true</code>, activates the window;358* otherwise, deactivates the window359*/360public void synthesizeWindowActivation(boolean doActivate) {}361362/**363* Moves this embedded frame to a new location. The top-left corner of364* the new location is specified by the <code>x</code> and <code>y</code>365* parameters relative to the native parent component.366* <p>367* setLocation() and setBounds() for EmbeddedFrame really don't move it368* within the native parent. These methods always put embedded frame to369* (0, 0) for backward compatibility. To allow moving embedded frame370* setLocationPrivate() and setBoundsPrivate() were introduced, and they371* work just the same way as setLocation() and setBounds() for usual,372* non-embedded components.373* </p>374* <p>375* Using usual get/setLocation() and get/setBounds() together with new376* get/setLocationPrivate() and get/setBoundsPrivate() is not recommended.377* For example, calling getBoundsPrivate() after setLocation() works fine,378* but getBounds() after setBoundsPrivate() may return unpredictable value.379* </p>380* @param x the new <i>x</i>-coordinate relative to the parent component381* @param y the new <i>y</i>-coordinate relative to the parent component382* @see java.awt.Component#setLocation383* @see #getLocationPrivate384* @see #setBoundsPrivate385* @see #getBoundsPrivate386* @since 1.5387*/388protected void setLocationPrivate(int x, int y) {389Dimension size = getSize();390setBoundsPrivate(x, y, size.width, size.height);391}392393/**394* Gets the location of this embedded frame as a point specifying the395* top-left corner relative to parent component.396* <p>397* setLocation() and setBounds() for EmbeddedFrame really don't move it398* within the native parent. These methods always put embedded frame to399* (0, 0) for backward compatibility. To allow getting location and size400* of embedded frame getLocationPrivate() and getBoundsPrivate() were401* introduced, and they work just the same way as getLocation() and getBounds()402* for ususal, non-embedded components.403* </p>404* <p>405* Using usual get/setLocation() and get/setBounds() together with new406* get/setLocationPrivate() and get/setBoundsPrivate() is not recommended.407* For example, calling getBoundsPrivate() after setLocation() works fine,408* but getBounds() after setBoundsPrivate() may return unpredictable value.409* </p>410* @return a point indicating this embedded frame's top-left corner411* @see java.awt.Component#getLocation412* @see #setLocationPrivate413* @see #setBoundsPrivate414* @see #getBoundsPrivate415* @since 1.6416*/417protected Point getLocationPrivate() {418Rectangle bounds = getBoundsPrivate();419return new Point(bounds.x, bounds.y);420}421422/**423* Moves and resizes this embedded frame. The new location of the top-left424* corner is specified by <code>x</code> and <code>y</code> parameters425* relative to the native parent component. The new size is specified by426* <code>width</code> and <code>height</code>.427* <p>428* setLocation() and setBounds() for EmbeddedFrame really don't move it429* within the native parent. These methods always put embedded frame to430* (0, 0) for backward compatibility. To allow moving embedded frames431* setLocationPrivate() and setBoundsPrivate() were introduced, and they432* work just the same way as setLocation() and setBounds() for usual,433* non-embedded components.434* </p>435* <p>436* Using usual get/setLocation() and get/setBounds() together with new437* get/setLocationPrivate() and get/setBoundsPrivate() is not recommended.438* For example, calling getBoundsPrivate() after setLocation() works fine,439* but getBounds() after setBoundsPrivate() may return unpredictable value.440* </p>441* @param x the new <i>x</i>-coordinate relative to the parent component442* @param y the new <i>y</i>-coordinate relative to the parent component443* @param width the new <code>width</code> of this embedded frame444* @param height the new <code>height</code> of this embedded frame445* @see java.awt.Component#setBounds446* @see #setLocationPrivate447* @see #getLocationPrivate448* @see #getBoundsPrivate449* @since 1.5450*/451@SuppressWarnings("deprecation")452protected void setBoundsPrivate(int x, int y, int width, int height) {453final FramePeer peer = (FramePeer)getPeer();454if (peer != null) {455peer.setBoundsPrivate(x, y, width, height);456}457}458459/**460* Gets the bounds of this embedded frame as a rectangle specifying the461* width, height and location relative to the native parent component.462* <p>463* setLocation() and setBounds() for EmbeddedFrame really don't move it464* within the native parent. These methods always put embedded frame to465* (0, 0) for backward compatibility. To allow getting location and size466* of embedded frames getLocationPrivate() and getBoundsPrivate() were467* introduced, and they work just the same way as getLocation() and getBounds()468* for ususal, non-embedded components.469* </p>470* <p>471* Using usual get/setLocation() and get/setBounds() together with new472* get/setLocationPrivate() and get/setBoundsPrivate() is not recommended.473* For example, calling getBoundsPrivate() after setLocation() works fine,474* but getBounds() after setBoundsPrivate() may return unpredictable value.475* </p>476* @return a rectangle indicating this embedded frame's bounds477* @see java.awt.Component#getBounds478* @see #setLocationPrivate479* @see #getLocationPrivate480* @see #setBoundsPrivate481* @since 1.6482*/483@SuppressWarnings("deprecation")484protected Rectangle getBoundsPrivate() {485final FramePeer peer = (FramePeer)getPeer();486if (peer != null) {487return peer.getBoundsPrivate();488}489else {490return getBounds();491}492}493494public void toFront() {}495public void toBack() {}496497public abstract void registerAccelerator(AWTKeyStroke stroke);498public abstract void unregisterAccelerator(AWTKeyStroke stroke);499500/**501* Checks if the component is in an EmbeddedFrame. If so,502* returns the applet found in the hierarchy or null if503* not found.504* @return the parent applet or {@ null}505* @since 1.6506*/507public static Applet getAppletIfAncestorOf(Component comp) {508Container parent = comp.getParent();509Applet applet = null;510while (parent != null && !(parent instanceof EmbeddedFrame)) {511if (parent instanceof Applet) {512applet = (Applet)parent;513}514parent = parent.getParent();515}516return parent == null ? null : applet;517}518519/**520* This method should be overriden in subclasses. It is521* called when window this frame is within should be blocked522* by some modal dialog.523*/524public void notifyModalBlocked(Dialog blocker, boolean blocked) {525}526527private static class NullEmbeddedFramePeer528extends NullComponentPeer implements FramePeer {529public void setTitle(String title) {}530public void setIconImage(Image im) {}531public void updateIconImages() {}532public void setMenuBar(MenuBar mb) {}533public void setResizable(boolean resizeable) {}534public void setState(int state) {}535public int getState() { return Frame.NORMAL; }536public void setMaximizedBounds(Rectangle b) {}537public void toFront() {}538public void toBack() {}539public void updateFocusableWindowState() {}540public void updateAlwaysOnTop() {}541public void updateAlwaysOnTopState() {}542public Component getGlobalHeavyweightFocusOwner() { return null; }543public void setBoundsPrivate(int x, int y, int width, int height) {544setBounds(x, y, width, height, SET_BOUNDS);545}546public Rectangle getBoundsPrivate() {547return getBounds();548}549public void setModalBlocked(Dialog blocker, boolean blocked) {}550551/**552* @see java.awt.peer.ContainerPeer#restack553*/554public void restack() {555throw new UnsupportedOperationException();556}557558/**559* @see java.awt.peer.ContainerPeer#isRestackSupported560*/561public boolean isRestackSupported() {562return false;563}564public boolean requestWindowFocus() {565return false;566}567public void updateMinimumSize() {568}569570public void setOpacity(float opacity) {571}572573public void setOpaque(boolean isOpaque) {574}575576public void updateWindow() {577}578579public void repositionSecurityWarning() {580}581582public void emulateActivation(boolean activate) {583}584}585} // class EmbeddedFrame586587588