src/java.desktop/share/classes/com/sun/awt/AWTUtilities.java
branchihse-jdk-library-branch
changeset 56434 69b4183fd7b8
parent 56433 c3cf838aa2da
parent 49704 bc1c7e41e285
child 56435 e177cddcbf77
equal deleted inserted replaced
56433:c3cf838aa2da 56434:69b4183fd7b8
     1 /*
       
     2  * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package com.sun.awt;
       
    27 
       
    28 import java.awt.Color;
       
    29 import java.awt.Component;
       
    30 import java.awt.Dialog;
       
    31 import java.awt.Frame;
       
    32 import java.awt.GraphicsConfiguration;
       
    33 import java.awt.GraphicsDevice;
       
    34 import java.awt.GraphicsEnvironment;
       
    35 import java.awt.Shape;
       
    36 import java.awt.Toolkit;
       
    37 import java.awt.Window;
       
    38 
       
    39 import javax.swing.JRootPane;
       
    40 
       
    41 import sun.awt.AWTAccessor;
       
    42 import sun.awt.SunToolkit;
       
    43 
       
    44 /**
       
    45  * A collection of utility methods for AWT.
       
    46  *
       
    47  * The functionality provided by the static methods of the class includes:
       
    48  * <ul>
       
    49  * <li>Setting shapes on top-level windows
       
    50  * <li>Setting a constant alpha value for each pixel of a top-level window
       
    51  * <li>Making a window non-opaque, after that it paints only explicitly
       
    52  * painted pixels on the screen, with arbitrary alpha values for every pixel.
       
    53  * <li>Setting a 'mixing-cutout' shape for a component.
       
    54  * </ul>
       
    55  * <p>
       
    56  * A "top-level window" is an instance of the {@code Window} class (or its
       
    57  * descendant, such as {@code JFrame}).
       
    58  * <p>
       
    59  * Some of the mentioned features may not be supported by the native platform.
       
    60  * To determine whether a particular feature is supported, the user must use
       
    61  * the {@code isTranslucencySupported()} method of the class passing a desired
       
    62  * translucency kind (a member of the {@code Translucency} enum) as an
       
    63  * argument.
       
    64  * <p>
       
    65  * The per-pixel alpha feature also requires the user to create her/his
       
    66  * windows using a translucency-capable graphics configuration.
       
    67  * The {@code isTranslucencyCapable()} method must
       
    68  * be used to verify whether any given GraphicsConfiguration supports
       
    69  * the translucency effects.
       
    70  * <p>
       
    71  * <b>WARNING</b>: This class is an implementation detail and only meant
       
    72  * for limited use outside of the core platform. This API may change
       
    73  * drastically between update release, and it may even be
       
    74  * removed or be moved in some other package(s)/class(es).
       
    75  */
       
    76 @Deprecated(forRemoval = true, since = "10")
       
    77 public final class AWTUtilities {
       
    78 
       
    79     /**
       
    80      * The AWTUtilities class should not be instantiated
       
    81      */
       
    82     private AWTUtilities() {
       
    83     }
       
    84 
       
    85     /** Kinds of translucency supported by the underlying system.
       
    86      *  @see #isTranslucencySupported
       
    87      */
       
    88     public static enum Translucency {
       
    89         /**
       
    90          * Represents support in the underlying system for windows each pixel
       
    91          * of which is guaranteed to be either completely opaque, with
       
    92          * an alpha value of 1.0, or completely transparent, with an alpha
       
    93          * value of 0.0.
       
    94          */
       
    95         PERPIXEL_TRANSPARENT,
       
    96 
       
    97         /**
       
    98          * Represents support in the underlying system for windows all of
       
    99          * the pixels of which have the same alpha value between or including
       
   100          * 0.0 and 1.0.
       
   101          */
       
   102         TRANSLUCENT,
       
   103 
       
   104         /**
       
   105          * Represents support in the underlying system for windows that
       
   106          * contain or might contain pixels with arbitrary alpha values
       
   107          * between and including 0.0 and 1.0.
       
   108          */
       
   109         PERPIXEL_TRANSLUCENT;
       
   110     }
       
   111 
       
   112 
       
   113     /**
       
   114      * Returns whether the given level of translucency is supported by
       
   115      * the underlying system.
       
   116      *
       
   117      * Note that this method may sometimes return the value
       
   118      * indicating that the particular level is supported, but
       
   119      * the native windowing system may still not support the
       
   120      * given level of translucency (due to the bugs in
       
   121      * the windowing system).
       
   122      *
       
   123      * @param translucencyKind a kind of translucency support
       
   124      *                         (either PERPIXEL_TRANSPARENT,
       
   125      *                         TRANSLUCENT, or PERPIXEL_TRANSLUCENT)
       
   126      * @return whether the given translucency kind is supported
       
   127      * @deprecated use {@link GraphicsDevice#isWindowTranslucencySupported}
       
   128      *             instead
       
   129      */
       
   130     @Deprecated(forRemoval = true, since = "10")
       
   131     public static boolean isTranslucencySupported(Translucency translucencyKind) {
       
   132         switch (translucencyKind) {
       
   133             case PERPIXEL_TRANSPARENT:
       
   134                 return isWindowShapingSupported();
       
   135             case TRANSLUCENT:
       
   136                 return isWindowOpacitySupported();
       
   137             case PERPIXEL_TRANSLUCENT:
       
   138                 return isWindowTranslucencySupported();
       
   139         }
       
   140         return false;
       
   141     }
       
   142 
       
   143 
       
   144     /**
       
   145      * Returns whether the windowing system supports changing the opacity
       
   146      * value of top-level windows.
       
   147      * Note that this method may sometimes return true, but the native
       
   148      * windowing system may still not support the concept of
       
   149      * translucency (due to the bugs in the windowing system).
       
   150      */
       
   151     private static boolean isWindowOpacitySupported() {
       
   152         Toolkit curToolkit = Toolkit.getDefaultToolkit();
       
   153         if (!(curToolkit instanceof SunToolkit)) {
       
   154             return false;
       
   155         }
       
   156         return ((SunToolkit)curToolkit).isWindowOpacitySupported();
       
   157     }
       
   158 
       
   159     /**
       
   160      * Set the opacity of the window. The opacity is at the range [0..1].
       
   161      * Note that setting the opacity level of 0 may or may not disable
       
   162      * the mouse event handling on this window. This is
       
   163      * a platform-dependent behavior.
       
   164      *
       
   165      * In order for this method to enable the translucency effect,
       
   166      * the isTranslucencySupported() method should indicate that the
       
   167      * TRANSLUCENT level of translucency is supported.
       
   168      *
       
   169      * <p>Also note that the window must not be in the full-screen mode
       
   170      * when setting the opacity value &lt; 1.0f. Otherwise
       
   171      * the IllegalArgumentException is thrown.
       
   172      *
       
   173      * @param window the window to set the opacity level to
       
   174      * @param opacity the opacity level to set to the window
       
   175      * @throws NullPointerException if the window argument is null
       
   176      * @throws IllegalArgumentException if the opacity is out of
       
   177      *                                  the range [0..1]
       
   178      * @throws IllegalArgumentException if the window is in full screen mode,
       
   179      *                                  and the opacity is less than 1.0f
       
   180      * @throws UnsupportedOperationException if the TRANSLUCENT translucency
       
   181      *                                       kind is not supported
       
   182      * @deprecated use {@link Window#setOpacity} instead
       
   183      */
       
   184     @Deprecated(forRemoval = true, since = "10")
       
   185     public static void setWindowOpacity(Window window, float opacity) {
       
   186         if (window == null) {
       
   187             throw new NullPointerException(
       
   188                     "The window argument should not be null.");
       
   189         }
       
   190         window.setOpacity(opacity);
       
   191     }
       
   192 
       
   193     /**
       
   194      * Get the opacity of the window. If the opacity has not
       
   195      * yet being set, this method returns 1.0.
       
   196      *
       
   197      * @param window the window to get the opacity level from
       
   198      * @throws NullPointerException if the window argument is null
       
   199      * @deprecated use {@link Window#getOpacity} instead
       
   200      */
       
   201     @Deprecated(forRemoval = true, since = "10")
       
   202     public static float getWindowOpacity(Window window) {
       
   203         if (window == null) {
       
   204             throw new NullPointerException(
       
   205                     "The window argument should not be null.");
       
   206         }
       
   207 
       
   208         return window.getOpacity();
       
   209     }
       
   210 
       
   211     /**
       
   212      * Returns whether the windowing system supports changing the shape
       
   213      * of top-level windows.
       
   214      * Note that this method may sometimes return true, but the native
       
   215      * windowing system may still not support the concept of
       
   216      * shaping (due to the bugs in the windowing system).
       
   217      * @deprecated use {@link GraphicsDevice#isWindowTranslucencySupported}
       
   218      *             instead
       
   219      */
       
   220     @Deprecated(forRemoval = true, since = "10")
       
   221     public static boolean isWindowShapingSupported() {
       
   222         Toolkit curToolkit = Toolkit.getDefaultToolkit();
       
   223         if (!(curToolkit instanceof SunToolkit)) {
       
   224             return false;
       
   225         }
       
   226         return ((SunToolkit)curToolkit).isWindowShapingSupported();
       
   227     }
       
   228 
       
   229     /**
       
   230      * Returns an object that implements the Shape interface and represents
       
   231      * the shape previously set with the call to the setWindowShape() method.
       
   232      * If no shape has been set yet, or the shape has been reset to null,
       
   233      * this method returns null.
       
   234      *
       
   235      * @param window the window to get the shape from
       
   236      * @return the current shape of the window
       
   237      * @throws NullPointerException if the window argument is null
       
   238      * @deprecated use {@link Window#getShape} instead
       
   239      */
       
   240     @Deprecated(forRemoval = true, since = "10")
       
   241     public static Shape getWindowShape(Window window) {
       
   242         if (window == null) {
       
   243             throw new NullPointerException(
       
   244                     "The window argument should not be null.");
       
   245         }
       
   246         return window.getShape();
       
   247     }
       
   248 
       
   249     /**
       
   250      * Sets a shape for the given window.
       
   251      * If the shape argument is null, this methods restores
       
   252      * the default shape making the window rectangular.
       
   253      * <p>Note that in order to set a shape, the window must be undecorated.
       
   254      * If the window is decorated, this method ignores the {@code shape}
       
   255      * argument and resets the shape to null.
       
   256      * <p>Also note that the window must not be in the full-screen mode
       
   257      * when setting a non-null shape. Otherwise the IllegalArgumentException
       
   258      * is thrown.
       
   259      * <p>Depending on the platform, the method may return without
       
   260      * effecting the shape of the window if the window has a non-null warning
       
   261      * string ({@link Window#getWarningString()}). In this case the passed
       
   262      * shape object is ignored.
       
   263      *
       
   264      * @param window the window to set the shape to
       
   265      * @param shape the shape to set to the window
       
   266      * @throws NullPointerException if the window argument is null
       
   267      * @throws IllegalArgumentException if the window is in full screen mode,
       
   268      *                                  and the shape is not null
       
   269      * @throws UnsupportedOperationException if the PERPIXEL_TRANSPARENT
       
   270      *                                       translucency kind is not supported
       
   271      * @deprecated use {@link Window#setShape} instead
       
   272      */
       
   273     @Deprecated(forRemoval = true, since = "10")
       
   274     public static void setWindowShape(Window window, Shape shape) {
       
   275         if (window == null) {
       
   276             throw new NullPointerException(
       
   277                     "The window argument should not be null.");
       
   278         }
       
   279         window.setShape(shape);
       
   280     }
       
   281 
       
   282     private static boolean isWindowTranslucencySupported() {
       
   283         /*
       
   284          * Per-pixel alpha is supported if all the conditions are TRUE:
       
   285          *    1. The toolkit is a sort of SunToolkit
       
   286          *    2. The toolkit supports translucency in general
       
   287          *        (isWindowTranslucencySupported())
       
   288          *    3. There's at least one translucency-capable
       
   289          *        GraphicsConfiguration
       
   290          */
       
   291 
       
   292         Toolkit curToolkit = Toolkit.getDefaultToolkit();
       
   293         if (!(curToolkit instanceof SunToolkit)) {
       
   294             return false;
       
   295         }
       
   296 
       
   297         if (!((SunToolkit)curToolkit).isWindowTranslucencySupported()) {
       
   298             return false;
       
   299         }
       
   300 
       
   301         GraphicsEnvironment env =
       
   302             GraphicsEnvironment.getLocalGraphicsEnvironment();
       
   303 
       
   304         // If the default GC supports translucency return true.
       
   305         // It is important to optimize the verification this way,
       
   306         // see CR 6661196 for more details.
       
   307         if (isTranslucencyCapable(env.getDefaultScreenDevice()
       
   308                     .getDefaultConfiguration()))
       
   309         {
       
   310             return true;
       
   311         }
       
   312 
       
   313         // ... otherwise iterate through all the GCs.
       
   314         GraphicsDevice[] devices = env.getScreenDevices();
       
   315 
       
   316         for (int i = 0; i < devices.length; i++) {
       
   317             GraphicsConfiguration[] configs = devices[i].getConfigurations();
       
   318             for (int j = 0; j < configs.length; j++) {
       
   319                 if (isTranslucencyCapable(configs[j])) {
       
   320                     return true;
       
   321                 }
       
   322             }
       
   323         }
       
   324 
       
   325         return false;
       
   326     }
       
   327 
       
   328     /**
       
   329      * Enables the per-pixel alpha support for the given window.
       
   330      * Once the window becomes non-opaque (the isOpaque is set to false),
       
   331      * the drawing sub-system is starting to respect the alpha value of each
       
   332      * separate pixel. If a pixel gets painted with alpha color component
       
   333      * equal to zero, it becomes visually transparent, if the alpha of the
       
   334      * pixel is equal to 255, the pixel is fully opaque. Interim values
       
   335      * of the alpha color component make the pixel semi-transparent (i.e.
       
   336      * translucent).
       
   337      * <p>Note that in order for the window to support the per-pixel alpha
       
   338      * mode, the window must be created using the GraphicsConfiguration
       
   339      * for which the {@link #isTranslucencyCapable}
       
   340      * method returns true.
       
   341      * <p>Also note that some native systems enable the per-pixel translucency
       
   342      * mode for any window created using the translucency-compatible
       
   343      * graphics configuration. However, it is highly recommended to always
       
   344      * invoke the setWindowOpaque() method for these windows, at least for
       
   345      * the sake of cross-platform compatibility reasons.
       
   346      * <p>Also note that the window must not be in the full-screen mode
       
   347      * when making it non-opaque. Otherwise the IllegalArgumentException
       
   348      * is thrown.
       
   349      * <p>If the window is a {@code Frame} or a {@code Dialog}, the window must
       
   350      * be undecorated prior to enabling the per-pixel translucency effect (see
       
   351      * {@link Frame#setUndecorated} and/or {@link Dialog#setUndecorated}).
       
   352      * If the window becomes decorated through a subsequent call to the
       
   353      * corresponding {@code setUndecorated()} method, the per-pixel
       
   354      * translucency effect will be disabled and the opaque property reset to
       
   355      * {@code true}.
       
   356      * <p>Depending on the platform, the method may return without
       
   357      * effecting the opaque property of the window if the window has a non-null
       
   358      * warning string ({@link Window#getWarningString()}). In this case
       
   359      * the passed 'isOpaque' value is ignored.
       
   360      *
       
   361      * @param window the window to set the shape to
       
   362      * @param isOpaque whether the window must be opaque (true),
       
   363      *                 or translucent (false)
       
   364      * @throws NullPointerException if the window argument is null
       
   365      * @throws IllegalArgumentException if the window uses
       
   366      *                                  a GraphicsConfiguration for which the
       
   367      *                                  {@code isTranslucencyCapable()}
       
   368      *                                  method returns false
       
   369      * @throws IllegalArgumentException if the window is in full screen mode,
       
   370      *                                  and the isOpaque is false
       
   371      * @throws IllegalArgumentException if the window is decorated and the
       
   372      * isOpaque argument is {@code false}.
       
   373      * @throws UnsupportedOperationException if the PERPIXEL_TRANSLUCENT
       
   374      *                                       translucency kind is not supported
       
   375      * @deprecated use {@link Window#setBackground} instead
       
   376      */
       
   377     @Deprecated(forRemoval = true, since = "10")
       
   378     public static void setWindowOpaque(Window window, boolean isOpaque) {
       
   379         if (window == null) {
       
   380             throw new NullPointerException(
       
   381                     "The window argument should not be null.");
       
   382         }
       
   383         if (!isOpaque && !isTranslucencySupported(Translucency.PERPIXEL_TRANSLUCENT)) {
       
   384             throw new UnsupportedOperationException(
       
   385                     "The PERPIXEL_TRANSLUCENT translucency kind is not supported");
       
   386         }
       
   387         Color bg = window.getBackground();
       
   388         if (bg == null) {
       
   389             bg = new Color(0, 0, 0, 0);
       
   390         }
       
   391         window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
       
   392                                        isOpaque ? 255 : 0));
       
   393     }
       
   394 
       
   395     /**
       
   396      * Returns whether the window is opaque or translucent.
       
   397      *
       
   398      * @param window the window to set the shape to
       
   399      * @return whether the window is currently opaque (true)
       
   400      *         or translucent (false)
       
   401      * @throws NullPointerException if the window argument is null
       
   402      * @deprecated use {@link Window#isOpaque} instead
       
   403      */
       
   404     @Deprecated(forRemoval = true, since = "10")
       
   405     public static boolean isWindowOpaque(Window window) {
       
   406         if (window == null) {
       
   407             throw new NullPointerException(
       
   408                     "The window argument should not be null.");
       
   409         }
       
   410 
       
   411         return window.isOpaque();
       
   412     }
       
   413 
       
   414     /**
       
   415      * Verifies whether a given GraphicsConfiguration supports
       
   416      * the PERPIXEL_TRANSLUCENT kind of translucency.
       
   417      * All windows that are intended to be used with the {@link #setWindowOpaque}
       
   418      * method must be created using a GraphicsConfiguration for which this method
       
   419      * returns true.
       
   420      * <p>Note that some native systems enable the per-pixel translucency
       
   421      * mode for any window created using a translucency-capable
       
   422      * graphics configuration. However, it is highly recommended to always
       
   423      * invoke the setWindowOpaque() method for these windows, at least
       
   424      * for the sake of cross-platform compatibility reasons.
       
   425      *
       
   426      * @param gc GraphicsConfiguration
       
   427      * @throws NullPointerException if the gc argument is null
       
   428      * @return whether the given GraphicsConfiguration supports
       
   429      *         the translucency effects.
       
   430      * @deprecated use {@link GraphicsConfiguration#isTranslucencyCapable}
       
   431      *             instead
       
   432      */
       
   433     @Deprecated(forRemoval = true, since = "10")
       
   434     public static boolean isTranslucencyCapable(GraphicsConfiguration gc) {
       
   435         if (gc == null) {
       
   436             throw new NullPointerException("The gc argument should not be null");
       
   437         }
       
   438         /*
       
   439         return gc.isTranslucencyCapable();
       
   440         */
       
   441         Toolkit curToolkit = Toolkit.getDefaultToolkit();
       
   442         if (!(curToolkit instanceof SunToolkit)) {
       
   443             return false;
       
   444         }
       
   445         return ((SunToolkit)curToolkit).isTranslucencyCapable(gc);
       
   446     }
       
   447 
       
   448     /**
       
   449      * Sets a 'mixing-cutout' shape for the given component.
       
   450      *
       
   451      * By default a lightweight component is treated as an opaque rectangle for
       
   452      * the purposes of the Heavyweight/Lightweight Components Mixing feature.
       
   453      * This method enables developers to set an arbitrary shape to be cut out
       
   454      * from heavyweight components positioned underneath the lightweight
       
   455      * component in the z-order.
       
   456      * <p>
       
   457      * The {@code shape} argument may have the following values:
       
   458      * <ul>
       
   459      * <li>{@code null} - reverts the default cutout shape (the rectangle equal
       
   460      * to the component's {@code getBounds()})
       
   461      * <li><i>empty-shape</i> - does not cut out anything from heavyweight
       
   462      * components. This makes the given lightweight component effectively
       
   463      * transparent. Note that descendants of the lightweight component still
       
   464      * affect the shapes of heavyweight components.  An example of an
       
   465      * <i>empty-shape</i> is {@code new Rectangle()}.
       
   466      * <li><i>non-empty-shape</i> - the given shape will be cut out from
       
   467      * heavyweight components.
       
   468      * </ul>
       
   469      * <p>
       
   470      * The most common example when the 'mixing-cutout' shape is needed is a
       
   471      * glass pane component. The {@link JRootPane#setGlassPane} method
       
   472      * automatically sets the <i>empty-shape</i> as the 'mixing-cutout' shape
       
   473      * for the given glass pane component.  If a developer needs some other
       
   474      * 'mixing-cutout' shape for the glass pane (which is rare), this must be
       
   475      * changed manually after installing the glass pane to the root pane.
       
   476      * <p>
       
   477      * Note that the 'mixing-cutout' shape neither affects painting, nor the
       
   478      * mouse events handling for the given component. It is used exclusively
       
   479      * for the purposes of the Heavyweight/Lightweight Components Mixing
       
   480      * feature.
       
   481      *
       
   482      * @param component the component that needs non-default
       
   483      * 'mixing-cutout' shape
       
   484      * @param shape the new 'mixing-cutout' shape
       
   485      * @throws NullPointerException if the component argument is {@code null}
       
   486      * @deprecated use {@link Component#setMixingCutoutShape} instead
       
   487      */
       
   488     @Deprecated(forRemoval = true, since = "9")
       
   489     public static void setComponentMixingCutoutShape(Component component,
       
   490             Shape shape)
       
   491     {
       
   492         if (component == null) {
       
   493             throw new NullPointerException(
       
   494                     "The component argument should not be null.");
       
   495         }
       
   496 
       
   497         component.setMixingCutoutShape(shape);
       
   498     }
       
   499 }
       
   500