Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/awt/AWTUtilities.java
38831 views
/*1* Copyright (c) 2008, 2009, 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 com.sun.awt;2627import java.awt.*;2829import sun.awt.AWTAccessor;30import sun.awt.SunToolkit;3132/**33* A collection of utility methods for AWT.34*35* The functionality provided by the static methods of the class includes:36* <ul>37* <li>Setting shapes on top-level windows38* <li>Setting a constant alpha value for each pixel of a top-level window39* <li>Making a window non-opaque, after that it paints only explicitly40* painted pixels on the screen, with arbitrary alpha values for every pixel.41* <li>Setting a 'mixing-cutout' shape for a component.42* </ul>43* <p>44* A "top-level window" is an instance of the {@code Window} class (or its45* descendant, such as {@code JFrame}).46* <p>47* Some of the mentioned features may not be supported by the native platform.48* To determine whether a particular feature is supported, the user must use49* the {@code isTranslucencySupported()} method of the class passing a desired50* translucency kind (a member of the {@code Translucency} enum) as an51* argument.52* <p>53* The per-pixel alpha feature also requires the user to create her/his54* windows using a translucency-capable graphics configuration.55* The {@code isTranslucencyCapable()} method must56* be used to verify whether any given GraphicsConfiguration supports57* the trasnlcency effects.58* <p>59* <b>WARNING</b>: This class is an implementation detail and only meant60* for limited use outside of the core platform. This API may change61* drastically between update release, and it may even be62* removed or be moved in some other package(s)/class(es).63*/64public final class AWTUtilities {6566/**67* The AWTUtilities class should not be instantiated68*/69private AWTUtilities() {70}7172/** Kinds of translucency supported by the underlying system.73* @see #isTranslucencySupported74*/75public static enum Translucency {76/**77* Represents support in the underlying system for windows each pixel78* of which is guaranteed to be either completely opaque, with79* an alpha value of 1.0, or completely transparent, with an alpha80* value of 0.0.81*/82PERPIXEL_TRANSPARENT,8384/**85* Represents support in the underlying system for windows all of86* the pixels of which have the same alpha value between or including87* 0.0 and 1.0.88*/89TRANSLUCENT,9091/**92* Represents support in the underlying system for windows that93* contain or might contain pixels with arbitrary alpha values94* between and including 0.0 and 1.0.95*/96PERPIXEL_TRANSLUCENT;97}9899100/**101* Returns whether the given level of translucency is supported by102* the underlying system.103*104* Note that this method may sometimes return the value105* indicating that the particular level is supported, but106* the native windowing system may still not support the107* given level of translucency (due to the bugs in108* the windowing system).109*110* @param translucencyKind a kind of translucency support111* (either PERPIXEL_TRANSPARENT,112* TRANSLUCENT, or PERPIXEL_TRANSLUCENT)113* @return whether the given translucency kind is supported114*/115public static boolean isTranslucencySupported(Translucency translucencyKind) {116switch (translucencyKind) {117case PERPIXEL_TRANSPARENT:118return isWindowShapingSupported();119case TRANSLUCENT:120return isWindowOpacitySupported();121case PERPIXEL_TRANSLUCENT:122return isWindowTranslucencySupported();123}124return false;125}126127128/**129* Returns whether the windowing system supports changing the opacity130* value of top-level windows.131* Note that this method may sometimes return true, but the native132* windowing system may still not support the concept of133* translucency (due to the bugs in the windowing system).134*/135private static boolean isWindowOpacitySupported() {136Toolkit curToolkit = Toolkit.getDefaultToolkit();137if (!(curToolkit instanceof SunToolkit)) {138return false;139}140return ((SunToolkit)curToolkit).isWindowOpacitySupported();141}142143/**144* Set the opacity of the window. The opacity is at the range [0..1].145* Note that setting the opacity level of 0 may or may not disable146* the mouse event handling on this window. This is147* a platform-dependent behavior.148*149* In order for this method to enable the translucency effect,150* the isTranslucencySupported() method should indicate that the151* TRANSLUCENT level of translucency is supported.152*153* <p>Also note that the window must not be in the full-screen mode154* when setting the opacity value < 1.0f. Otherwise155* the IllegalArgumentException is thrown.156*157* @param window the window to set the opacity level to158* @param opacity the opacity level to set to the window159* @throws NullPointerException if the window argument is null160* @throws IllegalArgumentException if the opacity is out of161* the range [0..1]162* @throws IllegalArgumentException if the window is in full screen mode,163* and the opacity is less than 1.0f164* @throws UnsupportedOperationException if the TRANSLUCENT translucency165* kind is not supported166*/167public static void setWindowOpacity(Window window, float opacity) {168if (window == null) {169throw new NullPointerException(170"The window argument should not be null.");171}172173AWTAccessor.getWindowAccessor().setOpacity(window, opacity);174}175176/**177* Get the opacity of the window. If the opacity has not178* yet being set, this method returns 1.0.179*180* @param window the window to get the opacity level from181* @throws NullPointerException if the window argument is null182*/183public static float getWindowOpacity(Window window) {184if (window == null) {185throw new NullPointerException(186"The window argument should not be null.");187}188189return AWTAccessor.getWindowAccessor().getOpacity(window);190}191192/**193* Returns whether the windowing system supports changing the shape194* of top-level windows.195* Note that this method may sometimes return true, but the native196* windowing system may still not support the concept of197* shaping (due to the bugs in the windowing system).198*/199public static boolean isWindowShapingSupported() {200Toolkit curToolkit = Toolkit.getDefaultToolkit();201if (!(curToolkit instanceof SunToolkit)) {202return false;203}204return ((SunToolkit)curToolkit).isWindowShapingSupported();205}206207/**208* Returns an object that implements the Shape interface and represents209* the shape previously set with the call to the setWindowShape() method.210* If no shape has been set yet, or the shape has been reset to null,211* this method returns null.212*213* @param window the window to get the shape from214* @return the current shape of the window215* @throws NullPointerException if the window argument is null216*/217public static Shape getWindowShape(Window window) {218if (window == null) {219throw new NullPointerException(220"The window argument should not be null.");221}222return AWTAccessor.getWindowAccessor().getShape(window);223}224225/**226* Sets a shape for the given window.227* If the shape argument is null, this methods restores228* the default shape making the window rectangular.229* <p>Note that in order to set a shape, the window must be undecorated.230* If the window is decorated, this method ignores the {@code shape}231* argument and resets the shape to null.232* <p>Also note that the window must not be in the full-screen mode233* when setting a non-null shape. Otherwise the IllegalArgumentException234* is thrown.235* <p>Depending on the platform, the method may return without236* effecting the shape of the window if the window has a non-null warning237* string ({@link Window#getWarningString()}). In this case the passed238* shape object is ignored.239*240* @param window the window to set the shape to241* @param shape the shape to set to the window242* @throws NullPointerException if the window argument is null243* @throws IllegalArgumentException if the window is in full screen mode,244* and the shape is not null245* @throws UnsupportedOperationException if the PERPIXEL_TRANSPARENT246* translucency kind is not supported247*/248public static void setWindowShape(Window window, Shape shape) {249if (window == null) {250throw new NullPointerException(251"The window argument should not be null.");252}253AWTAccessor.getWindowAccessor().setShape(window, shape);254}255256private static boolean isWindowTranslucencySupported() {257/*258* Per-pixel alpha is supported if all the conditions are TRUE:259* 1. The toolkit is a sort of SunToolkit260* 2. The toolkit supports translucency in general261* (isWindowTranslucencySupported())262* 3. There's at least one translucency-capable263* GraphicsConfiguration264*/265266Toolkit curToolkit = Toolkit.getDefaultToolkit();267if (!(curToolkit instanceof SunToolkit)) {268return false;269}270271if (!((SunToolkit)curToolkit).isWindowTranslucencySupported()) {272return false;273}274275GraphicsEnvironment env =276GraphicsEnvironment.getLocalGraphicsEnvironment();277278// If the default GC supports translucency return true.279// It is important to optimize the verification this way,280// see CR 6661196 for more details.281if (isTranslucencyCapable(env.getDefaultScreenDevice()282.getDefaultConfiguration()))283{284return true;285}286287// ... otherwise iterate through all the GCs.288GraphicsDevice[] devices = env.getScreenDevices();289290for (int i = 0; i < devices.length; i++) {291GraphicsConfiguration[] configs = devices[i].getConfigurations();292for (int j = 0; j < configs.length; j++) {293if (isTranslucencyCapable(configs[j])) {294return true;295}296}297}298299return false;300}301302/**303* Enables the per-pixel alpha support for the given window.304* Once the window becomes non-opaque (the isOpaque is set to false),305* the drawing sub-system is starting to respect the alpha value of each306* separate pixel. If a pixel gets painted with alpha color component307* equal to zero, it becomes visually transparent, if the alpha of the308* pixel is equal to 255, the pixel is fully opaque. Interim values309* of the alpha color component make the pixel semi-transparent (i.e.310* translucent).311* <p>Note that in order for the window to support the per-pixel alpha312* mode, the window must be created using the GraphicsConfiguration313* for which the {@link #isTranslucencyCapable}314* method returns true.315* <p>Also note that some native systems enable the per-pixel translucency316* mode for any window created using the translucency-compatible317* graphics configuration. However, it is highly recommended to always318* invoke the setWindowOpaque() method for these windows, at least for319* the sake of cross-platform compatibility reasons.320* <p>Also note that the window must not be in the full-screen mode321* when making it non-opaque. Otherwise the IllegalArgumentException322* is thrown.323* <p>If the window is a {@code Frame} or a {@code Dialog}, the window must324* be undecorated prior to enabling the per-pixel translucency effect (see325* {@link Frame#setUndecorated()} and/or {@link Dialog#setUndecorated()}).326* If the window becomes decorated through a subsequent call to the327* corresponding {@code setUndecorated()} method, the per-pixel328* translucency effect will be disabled and the opaque property reset to329* {@code true}.330* <p>Depending on the platform, the method may return without331* effecting the opaque property of the window if the window has a non-null332* warning string ({@link Window#getWarningString()}). In this case333* the passed 'isOpaque' value is ignored.334*335* @param window the window to set the shape to336* @param isOpaque whether the window must be opaque (true),337* or translucent (false)338* @throws NullPointerException if the window argument is null339* @throws IllegalArgumentException if the window uses340* a GraphicsConfiguration for which the341* {@code isTranslucencyCapable()}342* method returns false343* @throws IllegalArgumentException if the window is in full screen mode,344* and the isOpaque is false345* @throws IllegalArgumentException if the window is decorated and the346* isOpaque argument is {@code false}.347* @throws UnsupportedOperationException if the PERPIXEL_TRANSLUCENT348* translucency kind is not supported349*/350public static void setWindowOpaque(Window window, boolean isOpaque) {351if (window == null) {352throw new NullPointerException(353"The window argument should not be null.");354}355if (!isOpaque && !isTranslucencySupported(Translucency.PERPIXEL_TRANSLUCENT)) {356throw new UnsupportedOperationException(357"The PERPIXEL_TRANSLUCENT translucency kind is not supported");358}359AWTAccessor.getWindowAccessor().setOpaque(window, isOpaque);360}361362/**363* Returns whether the window is opaque or translucent.364*365* @param window the window to set the shape to366* @return whether the window is currently opaque (true)367* or translucent (false)368* @throws NullPointerException if the window argument is null369*/370public static boolean isWindowOpaque(Window window) {371if (window == null) {372throw new NullPointerException(373"The window argument should not be null.");374}375376return window.isOpaque();377}378379/**380* Verifies whether a given GraphicsConfiguration supports381* the PERPIXEL_TRANSLUCENT kind of translucency.382* All windows that are intended to be used with the {@link #setWindowOpaque}383* method must be created using a GraphicsConfiguration for which this method384* returns true.385* <p>Note that some native systems enable the per-pixel translucency386* mode for any window created using a translucency-capable387* graphics configuration. However, it is highly recommended to always388* invoke the setWindowOpaque() method for these windows, at least389* for the sake of cross-platform compatibility reasons.390*391* @param gc GraphicsConfiguration392* @throws NullPointerException if the gc argument is null393* @return whether the given GraphicsConfiguration supports394* the translucency effects.395*/396public static boolean isTranslucencyCapable(GraphicsConfiguration gc) {397if (gc == null) {398throw new NullPointerException("The gc argument should not be null");399}400/*401return gc.isTranslucencyCapable();402*/403Toolkit curToolkit = Toolkit.getDefaultToolkit();404if (!(curToolkit instanceof SunToolkit)) {405return false;406}407return ((SunToolkit)curToolkit).isTranslucencyCapable(gc);408}409410/**411* Sets a 'mixing-cutout' shape for the given component.412*413* By default a lightweight component is treated as an opaque rectangle for414* the purposes of the Heavyweight/Lightweight Components Mixing feature.415* This method enables developers to set an arbitrary shape to be cut out416* from heavyweight components positioned underneath the lightweight417* component in the z-order.418* <p>419* The {@code shape} argument may have the following values:420* <ul>421* <li>{@code null} - reverts the default cutout shape (the rectangle equal422* to the component's {@code getBounds()})423* <li><i>empty-shape</i> - does not cut out anything from heavyweight424* components. This makes the given lightweight component effectively425* transparent. Note that descendants of the lightweight component still426* affect the shapes of heavyweight components. An example of an427* <i>empty-shape</i> is {@code new Rectangle()}.428* <li><i>non-empty-shape</i> - the given shape will be cut out from429* heavyweight components.430* </ul>431* <p>432* The most common example when the 'mixing-cutout' shape is needed is a433* glass pane component. The {@link JRootPane#setGlassPane()} method434* automatically sets the <i>empty-shape</i> as the 'mixing-cutout' shape435* for the given glass pane component. If a developer needs some other436* 'mixing-cutout' shape for the glass pane (which is rare), this must be437* changed manually after installing the glass pane to the root pane.438* <p>439* Note that the 'mixing-cutout' shape neither affects painting, nor the440* mouse events handling for the given component. It is used exclusively441* for the purposes of the Heavyweight/Lightweight Components Mixing442* feature.443*444* @param component the component that needs non-default445* 'mixing-cutout' shape446* @param shape the new 'mixing-cutout' shape447* @throws NullPointerException if the component argument is {@code null}448*/449public static void setComponentMixingCutoutShape(Component component,450Shape shape)451{452if (component == null) {453throw new NullPointerException(454"The component argument should not be null.");455}456457AWTAccessor.getComponentAccessor().setMixingCutoutShape(component,458shape);459}460}461462463464