1 /*
2 * Copyright (c) 1995, 2014, 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 package java.awt;
26
27 import java.awt.event.*;
28 import java.awt.geom.Path2D;
29 import java.awt.geom.Point2D;
30 import java.awt.im.InputContext;
31 import java.awt.image.BufferStrategy;
32 import java.awt.image.BufferedImage;
33 import java.awt.peer.ComponentPeer;
34 import java.awt.peer.WindowPeer;
35 import java.beans.PropertyChangeListener;
36 import java.io.IOException;
37 import java.io.ObjectInputStream;
38 import java.io.ObjectOutputStream;
39 import java.io.OptionalDataException;
40 import java.io.Serializable;
41 import java.lang.ref.WeakReference;
42 import java.lang.reflect.InvocationTargetException;
43 import java.security.AccessController;
44 import java.util.ArrayList;
45 import java.util.Arrays;
46 import java.util.EventListener;
47 import java.util.Locale;
48 import java.util.ResourceBundle;
49 import java.util.Set;
50 import java.util.Vector;
51 import java.util.concurrent.atomic.AtomicBoolean;
52 import javax.accessibility.*;
53 import sun.awt.AWTAccessor;
54 import sun.awt.AWTPermissions;
55 import sun.awt.AppContext;
56 import sun.awt.CausedFocusEvent;
57 import sun.awt.SunToolkit;
58 import sun.awt.util.IdentityArrayList;
59 import sun.java2d.Disposer;
60 import sun.java2d.pipe.Region;
61 import sun.security.action.GetPropertyAction;
62 import sun.util.logging.PlatformLogger;
63
64 /**
65 * A {@code Window} object is a top-level window with no borders and no
66 * menubar.
67 * The default layout for a window is {@code BorderLayout}.
68 * <p>
69 * A window must have either a frame, dialog, or another window defined as its
70 * owner when it's constructed.
71 * <p>
72 * In a multi-screen environment, you can create a {@code Window}
73 * on a different screen device by constructing the {@code Window}
74 * with {@link #Window(Window, GraphicsConfiguration)}. The
75 * {@code GraphicsConfiguration} object is one of the
76 * {@code GraphicsConfiguration} objects of the target screen device.
77 * <p>
78 * In a virtual device multi-screen environment in which the desktop
79 * area could span multiple physical screen devices, the bounds of all
738 * @see #getIconImages()
739 * @since 1.6
740 */
741 public void setIconImage(Image image) {
742 ArrayList<Image> imageList = new ArrayList<Image>();
743 if (image != null) {
744 imageList.add(image);
745 }
746 setIconImages(imageList);
747 }
748
749 /**
750 * Makes this Window displayable by creating the connection to its
751 * native screen resource.
752 * This method is called internally by the toolkit and should
753 * not be called directly by programs.
754 * @see Component#isDisplayable
755 * @see Container#removeNotify
756 * @since 1.0
757 */
758 @SuppressWarnings("deprecation")
759 public void addNotify() {
760 synchronized (getTreeLock()) {
761 Container parent = this.parent;
762 if (parent != null && parent.getPeer() == null) {
763 parent.addNotify();
764 }
765 if (peer == null) {
766 peer = getToolkit().createWindow(this);
767 }
768 synchronized (allWindows) {
769 allWindows.add(this);
770 }
771 super.addNotify();
772 }
773 }
774
775 /**
776 * {@inheritDoc}
777 */
778 public void removeNotify() {
779 synchronized (getTreeLock()) {
780 synchronized (allWindows) {
781 allWindows.remove(this);
782 }
785 }
786
787 /**
788 * Causes this Window to be sized to fit the preferred size
789 * and layouts of its subcomponents. The resulting width and
790 * height of the window are automatically enlarged if either
791 * of dimensions is less than the minimum size as specified
792 * by the previous call to the {@code setMinimumSize} method.
793 * <p>
794 * If the window and/or its owner are not displayable yet,
795 * both of them are made displayable before calculating
796 * the preferred size. The Window is validated after its
797 * size is being calculated.
798 *
799 * @see Component#isDisplayable
800 * @see #setMinimumSize
801 */
802 @SuppressWarnings("deprecation")
803 public void pack() {
804 Container parent = this.parent;
805 if (parent != null && parent.getPeer() == null) {
806 parent.addNotify();
807 }
808 if (peer == null) {
809 addNotify();
810 }
811 Dimension newSize = getPreferredSize();
812 if (peer != null) {
813 setClientSize(newSize.width, newSize.height);
814 }
815
816 if(beforeFirstShow) {
817 isPacked = true;
818 }
819
820 validateUnconditionally();
821 }
822
823 /**
824 * Sets the minimum size of this window to a constant
825 * value. Subsequent calls to {@code getMinimumSize}
1055 if (!isModalBlocked()) {
1056 updateChildrenBlocking();
1057 } else {
1058 // fix for 6532736: after this window is shown, its blocker
1059 // should be raised to front
1060 modalBlocker.toFront_NoClientCode();
1061 }
1062 if (this instanceof Frame || this instanceof Dialog) {
1063 updateChildFocusableWindowState(this);
1064 }
1065 }
1066 isInShow = false;
1067
1068 // If first time shown, generate WindowOpened event
1069 if ((state & OPENED) == 0) {
1070 postWindowEvent(WindowEvent.WINDOW_OPENED);
1071 state |= OPENED;
1072 }
1073 }
1074
1075 @SuppressWarnings("deprecation")
1076 static void updateChildFocusableWindowState(Window w) {
1077 if (w.getPeer() != null && w.isShowing()) {
1078 ((WindowPeer)w.getPeer()).updateFocusableWindowState();
1079 }
1080 for (int i = 0; i < w.ownedWindowList.size(); i++) {
1081 Window child = w.ownedWindowList.elementAt(i).get();
1082 if (child != null) {
1083 updateChildFocusableWindowState(child);
1084 }
1085 }
1086 }
1087
1088 synchronized void postWindowEvent(int id) {
1089 if (windowListener != null
1090 || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0
1091 || Toolkit.enabledOnToolkit(AWTEvent.WINDOW_EVENT_MASK)) {
1092 WindowEvent e = new WindowEvent(this, id);
1093 Toolkit.getEventQueue().postEvent(e);
1094 }
1095 }
1096
1097 /**
1098 * Hide this Window, its subcomponents, and all of its owned children.
1143 * those actions).
1144 * <p>
1145 * <b>Note</b>: When the last displayable window
1146 * within the Java virtual machine (VM) is disposed of, the VM may
1147 * terminate. See <a href="doc-files/AWTThreadIssues.html#Autoshutdown">
1148 * AWT Threading Issues</a> for more information.
1149 * @see Component#isDisplayable
1150 * @see #pack
1151 * @see #show
1152 */
1153 public void dispose() {
1154 doDispose();
1155 }
1156
1157 /*
1158 * Fix for 4872170.
1159 * If dispose() is called on parent then its children have to be disposed as well
1160 * as reported in javadoc. So we need to implement this functionality even if a
1161 * child overrides dispose() in a wrong way without calling super.dispose().
1162 */
1163 @SuppressWarnings("deprecation")
1164 void disposeImpl() {
1165 dispose();
1166 if (getPeer() != null) {
1167 doDispose();
1168 }
1169 }
1170
1171 void doDispose() {
1172 class DisposeAction implements Runnable {
1173 public void run() {
1174 disposing = true;
1175 try {
1176 // Check if this window is the fullscreen window for the
1177 // device. Exit the fullscreen mode prior to disposing
1178 // of the window if that's the case.
1179 GraphicsDevice gd = getGraphicsConfiguration().getDevice();
1180 if (gd.getFullScreenWindow() == Window.this) {
1181 gd.setFullScreenWindow(null);
1182 }
1183
1184 Object[] ownedWindowArray;
1185 synchronized(ownedWindowList) {
1186 ownedWindowArray = new Object[ownedWindowList.size()];
3632 synchronized (getTreeLock()) {
3633 if (opacity < 0.0f || opacity > 1.0f) {
3634 throw new IllegalArgumentException(
3635 "The value of opacity should be in the range [0.0f .. 1.0f].");
3636 }
3637 if (opacity < 1.0f) {
3638 GraphicsConfiguration gc = getGraphicsConfiguration();
3639 GraphicsDevice gd = gc.getDevice();
3640 if (gc.getDevice().getFullScreenWindow() == this) {
3641 throw new IllegalComponentStateException(
3642 "Setting opacity for full-screen window is not supported.");
3643 }
3644 if (!gd.isWindowTranslucencySupported(
3645 GraphicsDevice.WindowTranslucency.TRANSLUCENT))
3646 {
3647 throw new UnsupportedOperationException(
3648 "TRANSLUCENT translucency is not supported.");
3649 }
3650 }
3651 this.opacity = opacity;
3652 WindowPeer peer = (WindowPeer)getPeer();
3653 if (peer != null) {
3654 peer.setOpacity(opacity);
3655 }
3656 }
3657 }
3658
3659 /**
3660 * Returns the shape of the window.
3661 *
3662 * The value returned by this method may not be the same as
3663 * previously set with {@code setShape(shape)}, but it is guaranteed
3664 * to represent the same shape.
3665 *
3666 * @return the shape of the window or {@code null} if no
3667 * shape is specified for the window
3668 *
3669 * @see Window#setShape(Shape)
3670 * @see GraphicsDevice.WindowTranslucency
3671 *
3672 * @since 1.7
3709 * @param shape the shape to set to the window
3710 *
3711 * @throws IllegalComponentStateException if the shape is not {@code
3712 * null} and the window is decorated
3713 * @throws IllegalComponentStateException if the shape is not {@code
3714 * null} and the window is in full-screen mode
3715 * @throws UnsupportedOperationException if the shape is not {@code
3716 * null} and {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSPARENT
3717 * PERPIXEL_TRANSPARENT} translucency is not supported
3718 *
3719 * @see Window#getShape()
3720 * @see Window#setBackground(Color)
3721 * @see Window#setOpacity(float)
3722 * @see Frame#isUndecorated
3723 * @see Dialog#isUndecorated
3724 * @see GraphicsDevice.WindowTranslucency
3725 * @see GraphicsDevice#isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency)
3726 *
3727 * @since 1.7
3728 */
3729 @SuppressWarnings("deprecation")
3730 public void setShape(Shape shape) {
3731 synchronized (getTreeLock()) {
3732 if (shape != null) {
3733 GraphicsConfiguration gc = getGraphicsConfiguration();
3734 GraphicsDevice gd = gc.getDevice();
3735 if (gc.getDevice().getFullScreenWindow() == this) {
3736 throw new IllegalComponentStateException(
3737 "Setting shape for full-screen window is not supported.");
3738 }
3739 if (!gd.isWindowTranslucencySupported(
3740 GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT))
3741 {
3742 throw new UnsupportedOperationException(
3743 "PERPIXEL_TRANSPARENT translucency is not supported.");
3744 }
3745 }
3746 this.shape = (shape == null) ? null : new Path2D.Float(shape);
3747 WindowPeer peer = (WindowPeer)getPeer();
3748 if (peer != null) {
3749 peer.applyShape(shape == null ? null : Region.getInstance(shape, null));
3750 }
3751 }
3752 }
3753
3754 /**
3755 * Gets the background color of this window.
3756 * <p>
3757 * Note that the alpha component of the returned color indicates whether
3758 * the window is in the non-opaque (per-pixel translucent) mode.
3759 *
3760 * @return this component's background color
3761 *
3762 * @see Window#setBackground(Color)
3763 * @see Window#isOpaque
3764 * @see GraphicsDevice.WindowTranslucency
3765 */
3766 @Override
3767 public Color getBackground() {
3827 * background color is less than {@code 1.0f} and the window is decorated
3828 * @throws IllegalComponentStateException if the alpha value of the given
3829 * background color is less than {@code 1.0f} and the window is in
3830 * full-screen mode
3831 * @throws UnsupportedOperationException if the alpha value of the given
3832 * background color is less than {@code 1.0f} and {@link
3833 * GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
3834 * PERPIXEL_TRANSLUCENT} translucency is not supported
3835 *
3836 * @see Window#getBackground
3837 * @see Window#isOpaque
3838 * @see Window#setOpacity(float)
3839 * @see Window#setShape(Shape)
3840 * @see Frame#isUndecorated
3841 * @see Dialog#isUndecorated
3842 * @see GraphicsDevice.WindowTranslucency
3843 * @see GraphicsDevice#isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency)
3844 * @see GraphicsConfiguration#isTranslucencyCapable()
3845 */
3846 @Override
3847 @SuppressWarnings("deprecation")
3848 public void setBackground(Color bgColor) {
3849 Color oldBg = getBackground();
3850 super.setBackground(bgColor);
3851 if (oldBg != null && oldBg.equals(bgColor)) {
3852 return;
3853 }
3854 int oldAlpha = oldBg != null ? oldBg.getAlpha() : 255;
3855 int alpha = bgColor != null ? bgColor.getAlpha() : 255;
3856 if ((oldAlpha == 255) && (alpha < 255)) { // non-opaque window
3857 GraphicsConfiguration gc = getGraphicsConfiguration();
3858 GraphicsDevice gd = gc.getDevice();
3859 if (gc.getDevice().getFullScreenWindow() == this) {
3860 throw new IllegalComponentStateException(
3861 "Making full-screen window non opaque is not supported.");
3862 }
3863 if (!gc.isTranslucencyCapable()) {
3864 GraphicsConfiguration capableGC = gd.getTranslucencyCapableGC();
3865 if (capableGC == null) {
3866 throw new UnsupportedOperationException(
3867 "PERPIXEL_TRANSLUCENT translucency is not supported");
3868 }
3869 setGraphicsConfiguration(capableGC);
3870 }
3871 setLayersOpaque(this, false);
3872 } else if ((oldAlpha < 255) && (alpha == 255)) {
3873 setLayersOpaque(this, true);
3874 }
3875 WindowPeer peer = (WindowPeer)getPeer();
3876 if (peer != null) {
3877 peer.setOpaque(alpha == 255);
3878 }
3879 }
3880
3881 /**
3882 * Indicates if the window is currently opaque.
3883 * <p>
3884 * The method returns {@code false} if the background color of the window
3885 * is not {@code null} and the alpha component of the color is less than
3886 * {@code 1.0f}. The method returns {@code true} otherwise.
3887 *
3888 * @return {@code true} if the window is opaque, {@code false} otherwise
3889 *
3890 * @see Window#getBackground
3891 * @see Window#setBackground(Color)
3892 * @since 1.7
3893 */
3894 @Override
3895 public boolean isOpaque() {
3896 Color bg = getBackground();
3897 return bg != null ? bg.getAlpha() == 255 : true;
3898 }
3899
3900 @SuppressWarnings("deprecation")
3901 private void updateWindow() {
3902 synchronized (getTreeLock()) {
3903 WindowPeer peer = (WindowPeer)getPeer();
3904 if (peer != null) {
3905 peer.updateWindow();
3906 }
3907 }
3908 }
3909
3910 /**
3911 * {@inheritDoc}
3912 *
3913 * @since 1.7
3914 */
3915 @Override
3916 public void paint(Graphics g) {
3917 if (!isOpaque()) {
3918 Graphics gg = g.create();
3919 try {
3920 if (gg instanceof Graphics2D) {
3921 gg.setColor(getBackground());
3922 ((Graphics2D)gg).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));
3923 gg.fillRect(0, 0, getWidth(), getHeight());
4071 bg = new Color(0, 0, 0, 0);
4072 }
4073 window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
4074 opaque ? 255 : 0));
4075 }
4076 public void updateWindow(Window window) {
4077 window.updateWindow();
4078 }
4079
4080 public Dimension getSecurityWarningSize(Window window) {
4081 return new Dimension(window.securityWarningWidth,
4082 window.securityWarningHeight);
4083 }
4084
4085 public void setSecurityWarningSize(Window window, int width, int height)
4086 {
4087 window.securityWarningWidth = width;
4088 window.securityWarningHeight = height;
4089 }
4090
4091 @SuppressWarnings("deprecation")
4092 public void setSecurityWarningPosition(Window window,
4093 Point2D point, float alignmentX, float alignmentY)
4094 {
4095 window.securityWarningPointX = point.getX();
4096 window.securityWarningPointY = point.getY();
4097 window.securityWarningAlignmentX = alignmentX;
4098 window.securityWarningAlignmentY = alignmentY;
4099
4100 synchronized (window.getTreeLock()) {
4101 WindowPeer peer = (WindowPeer)window.getPeer();
4102 if (peer != null) {
4103 peer.repositionSecurityWarning();
4104 }
4105 }
4106 }
4107
4108 public Point2D calculateSecurityWarningPosition(Window window,
4109 double x, double y, double w, double h)
4110 {
4111 return window.calculateSecurityWarningPosition(x, y, w, h);
4112 }
4113
4114 public void setLWRequestStatus(Window changed, boolean status) {
4115 changed.syncLWRequests = status;
4116 }
4117
4118 public boolean isAutoRequestFocus(Window w) {
4119 return w.autoRequestFocus;
4120 }
4121
|
1 /*
2 * Copyright (c) 1995, 2015, 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 package java.awt;
26
27 import java.awt.event.*;
28 import java.awt.geom.Path2D;
29 import java.awt.geom.Point2D;
30 import java.awt.im.InputContext;
31 import java.awt.image.BufferStrategy;
32 import java.awt.peer.ComponentPeer;
33 import java.awt.peer.WindowPeer;
34 import java.beans.PropertyChangeListener;
35 import java.io.IOException;
36 import java.io.ObjectInputStream;
37 import java.io.ObjectOutputStream;
38 import java.io.OptionalDataException;
39 import java.io.Serializable;
40 import java.lang.ref.WeakReference;
41 import java.lang.reflect.InvocationTargetException;
42 import java.security.AccessController;
43 import java.util.ArrayList;
44 import java.util.Arrays;
45 import java.util.EventListener;
46 import java.util.Locale;
47 import java.util.ResourceBundle;
48 import java.util.Set;
49 import java.util.Vector;
50 import java.util.concurrent.atomic.AtomicBoolean;
51 import javax.accessibility.*;
52 import sun.awt.AWTAccessor;
53 import sun.awt.AWTPermissions;
54 import sun.awt.AppContext;
55 import sun.awt.CausedFocusEvent;
56 import sun.awt.SunToolkit;
57 import sun.awt.util.IdentityArrayList;
58 import sun.java2d.pipe.Region;
59 import sun.security.action.GetPropertyAction;
60 import sun.util.logging.PlatformLogger;
61
62 /**
63 * A {@code Window} object is a top-level window with no borders and no
64 * menubar.
65 * The default layout for a window is {@code BorderLayout}.
66 * <p>
67 * A window must have either a frame, dialog, or another window defined as its
68 * owner when it's constructed.
69 * <p>
70 * In a multi-screen environment, you can create a {@code Window}
71 * on a different screen device by constructing the {@code Window}
72 * with {@link #Window(Window, GraphicsConfiguration)}. The
73 * {@code GraphicsConfiguration} object is one of the
74 * {@code GraphicsConfiguration} objects of the target screen device.
75 * <p>
76 * In a virtual device multi-screen environment in which the desktop
77 * area could span multiple physical screen devices, the bounds of all
736 * @see #getIconImages()
737 * @since 1.6
738 */
739 public void setIconImage(Image image) {
740 ArrayList<Image> imageList = new ArrayList<Image>();
741 if (image != null) {
742 imageList.add(image);
743 }
744 setIconImages(imageList);
745 }
746
747 /**
748 * Makes this Window displayable by creating the connection to its
749 * native screen resource.
750 * This method is called internally by the toolkit and should
751 * not be called directly by programs.
752 * @see Component#isDisplayable
753 * @see Container#removeNotify
754 * @since 1.0
755 */
756 public void addNotify() {
757 synchronized (getTreeLock()) {
758 Container parent = this.parent;
759 if (parent != null && parent.peer == null) {
760 parent.addNotify();
761 }
762 if (peer == null) {
763 peer = getToolkit().createWindow(this);
764 }
765 synchronized (allWindows) {
766 allWindows.add(this);
767 }
768 super.addNotify();
769 }
770 }
771
772 /**
773 * {@inheritDoc}
774 */
775 public void removeNotify() {
776 synchronized (getTreeLock()) {
777 synchronized (allWindows) {
778 allWindows.remove(this);
779 }
782 }
783
784 /**
785 * Causes this Window to be sized to fit the preferred size
786 * and layouts of its subcomponents. The resulting width and
787 * height of the window are automatically enlarged if either
788 * of dimensions is less than the minimum size as specified
789 * by the previous call to the {@code setMinimumSize} method.
790 * <p>
791 * If the window and/or its owner are not displayable yet,
792 * both of them are made displayable before calculating
793 * the preferred size. The Window is validated after its
794 * size is being calculated.
795 *
796 * @see Component#isDisplayable
797 * @see #setMinimumSize
798 */
799 @SuppressWarnings("deprecation")
800 public void pack() {
801 Container parent = this.parent;
802 if (parent != null && parent.peer == null) {
803 parent.addNotify();
804 }
805 if (peer == null) {
806 addNotify();
807 }
808 Dimension newSize = getPreferredSize();
809 if (peer != null) {
810 setClientSize(newSize.width, newSize.height);
811 }
812
813 if(beforeFirstShow) {
814 isPacked = true;
815 }
816
817 validateUnconditionally();
818 }
819
820 /**
821 * Sets the minimum size of this window to a constant
822 * value. Subsequent calls to {@code getMinimumSize}
1052 if (!isModalBlocked()) {
1053 updateChildrenBlocking();
1054 } else {
1055 // fix for 6532736: after this window is shown, its blocker
1056 // should be raised to front
1057 modalBlocker.toFront_NoClientCode();
1058 }
1059 if (this instanceof Frame || this instanceof Dialog) {
1060 updateChildFocusableWindowState(this);
1061 }
1062 }
1063 isInShow = false;
1064
1065 // If first time shown, generate WindowOpened event
1066 if ((state & OPENED) == 0) {
1067 postWindowEvent(WindowEvent.WINDOW_OPENED);
1068 state |= OPENED;
1069 }
1070 }
1071
1072 static void updateChildFocusableWindowState(Window w) {
1073 if (w.peer != null && w.isShowing()) {
1074 ((WindowPeer)w.peer).updateFocusableWindowState();
1075 }
1076 for (int i = 0; i < w.ownedWindowList.size(); i++) {
1077 Window child = w.ownedWindowList.elementAt(i).get();
1078 if (child != null) {
1079 updateChildFocusableWindowState(child);
1080 }
1081 }
1082 }
1083
1084 synchronized void postWindowEvent(int id) {
1085 if (windowListener != null
1086 || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0
1087 || Toolkit.enabledOnToolkit(AWTEvent.WINDOW_EVENT_MASK)) {
1088 WindowEvent e = new WindowEvent(this, id);
1089 Toolkit.getEventQueue().postEvent(e);
1090 }
1091 }
1092
1093 /**
1094 * Hide this Window, its subcomponents, and all of its owned children.
1139 * those actions).
1140 * <p>
1141 * <b>Note</b>: When the last displayable window
1142 * within the Java virtual machine (VM) is disposed of, the VM may
1143 * terminate. See <a href="doc-files/AWTThreadIssues.html#Autoshutdown">
1144 * AWT Threading Issues</a> for more information.
1145 * @see Component#isDisplayable
1146 * @see #pack
1147 * @see #show
1148 */
1149 public void dispose() {
1150 doDispose();
1151 }
1152
1153 /*
1154 * Fix for 4872170.
1155 * If dispose() is called on parent then its children have to be disposed as well
1156 * as reported in javadoc. So we need to implement this functionality even if a
1157 * child overrides dispose() in a wrong way without calling super.dispose().
1158 */
1159 void disposeImpl() {
1160 dispose();
1161 if (peer != null) {
1162 doDispose();
1163 }
1164 }
1165
1166 void doDispose() {
1167 class DisposeAction implements Runnable {
1168 public void run() {
1169 disposing = true;
1170 try {
1171 // Check if this window is the fullscreen window for the
1172 // device. Exit the fullscreen mode prior to disposing
1173 // of the window if that's the case.
1174 GraphicsDevice gd = getGraphicsConfiguration().getDevice();
1175 if (gd.getFullScreenWindow() == Window.this) {
1176 gd.setFullScreenWindow(null);
1177 }
1178
1179 Object[] ownedWindowArray;
1180 synchronized(ownedWindowList) {
1181 ownedWindowArray = new Object[ownedWindowList.size()];
3627 synchronized (getTreeLock()) {
3628 if (opacity < 0.0f || opacity > 1.0f) {
3629 throw new IllegalArgumentException(
3630 "The value of opacity should be in the range [0.0f .. 1.0f].");
3631 }
3632 if (opacity < 1.0f) {
3633 GraphicsConfiguration gc = getGraphicsConfiguration();
3634 GraphicsDevice gd = gc.getDevice();
3635 if (gc.getDevice().getFullScreenWindow() == this) {
3636 throw new IllegalComponentStateException(
3637 "Setting opacity for full-screen window is not supported.");
3638 }
3639 if (!gd.isWindowTranslucencySupported(
3640 GraphicsDevice.WindowTranslucency.TRANSLUCENT))
3641 {
3642 throw new UnsupportedOperationException(
3643 "TRANSLUCENT translucency is not supported.");
3644 }
3645 }
3646 this.opacity = opacity;
3647 WindowPeer peer = (WindowPeer) this.peer;
3648 if (peer != null) {
3649 peer.setOpacity(opacity);
3650 }
3651 }
3652 }
3653
3654 /**
3655 * Returns the shape of the window.
3656 *
3657 * The value returned by this method may not be the same as
3658 * previously set with {@code setShape(shape)}, but it is guaranteed
3659 * to represent the same shape.
3660 *
3661 * @return the shape of the window or {@code null} if no
3662 * shape is specified for the window
3663 *
3664 * @see Window#setShape(Shape)
3665 * @see GraphicsDevice.WindowTranslucency
3666 *
3667 * @since 1.7
3704 * @param shape the shape to set to the window
3705 *
3706 * @throws IllegalComponentStateException if the shape is not {@code
3707 * null} and the window is decorated
3708 * @throws IllegalComponentStateException if the shape is not {@code
3709 * null} and the window is in full-screen mode
3710 * @throws UnsupportedOperationException if the shape is not {@code
3711 * null} and {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSPARENT
3712 * PERPIXEL_TRANSPARENT} translucency is not supported
3713 *
3714 * @see Window#getShape()
3715 * @see Window#setBackground(Color)
3716 * @see Window#setOpacity(float)
3717 * @see Frame#isUndecorated
3718 * @see Dialog#isUndecorated
3719 * @see GraphicsDevice.WindowTranslucency
3720 * @see GraphicsDevice#isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency)
3721 *
3722 * @since 1.7
3723 */
3724 public void setShape(Shape shape) {
3725 synchronized (getTreeLock()) {
3726 if (shape != null) {
3727 GraphicsConfiguration gc = getGraphicsConfiguration();
3728 GraphicsDevice gd = gc.getDevice();
3729 if (gc.getDevice().getFullScreenWindow() == this) {
3730 throw new IllegalComponentStateException(
3731 "Setting shape for full-screen window is not supported.");
3732 }
3733 if (!gd.isWindowTranslucencySupported(
3734 GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT))
3735 {
3736 throw new UnsupportedOperationException(
3737 "PERPIXEL_TRANSPARENT translucency is not supported.");
3738 }
3739 }
3740 this.shape = (shape == null) ? null : new Path2D.Float(shape);
3741 WindowPeer peer = (WindowPeer) this.peer;
3742 if (peer != null) {
3743 peer.applyShape(shape == null ? null : Region.getInstance(shape, null));
3744 }
3745 }
3746 }
3747
3748 /**
3749 * Gets the background color of this window.
3750 * <p>
3751 * Note that the alpha component of the returned color indicates whether
3752 * the window is in the non-opaque (per-pixel translucent) mode.
3753 *
3754 * @return this component's background color
3755 *
3756 * @see Window#setBackground(Color)
3757 * @see Window#isOpaque
3758 * @see GraphicsDevice.WindowTranslucency
3759 */
3760 @Override
3761 public Color getBackground() {
3821 * background color is less than {@code 1.0f} and the window is decorated
3822 * @throws IllegalComponentStateException if the alpha value of the given
3823 * background color is less than {@code 1.0f} and the window is in
3824 * full-screen mode
3825 * @throws UnsupportedOperationException if the alpha value of the given
3826 * background color is less than {@code 1.0f} and {@link
3827 * GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
3828 * PERPIXEL_TRANSLUCENT} translucency is not supported
3829 *
3830 * @see Window#getBackground
3831 * @see Window#isOpaque
3832 * @see Window#setOpacity(float)
3833 * @see Window#setShape(Shape)
3834 * @see Frame#isUndecorated
3835 * @see Dialog#isUndecorated
3836 * @see GraphicsDevice.WindowTranslucency
3837 * @see GraphicsDevice#isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency)
3838 * @see GraphicsConfiguration#isTranslucencyCapable()
3839 */
3840 @Override
3841 public void setBackground(Color bgColor) {
3842 Color oldBg = getBackground();
3843 super.setBackground(bgColor);
3844 if (oldBg != null && oldBg.equals(bgColor)) {
3845 return;
3846 }
3847 int oldAlpha = oldBg != null ? oldBg.getAlpha() : 255;
3848 int alpha = bgColor != null ? bgColor.getAlpha() : 255;
3849 if ((oldAlpha == 255) && (alpha < 255)) { // non-opaque window
3850 GraphicsConfiguration gc = getGraphicsConfiguration();
3851 GraphicsDevice gd = gc.getDevice();
3852 if (gc.getDevice().getFullScreenWindow() == this) {
3853 throw new IllegalComponentStateException(
3854 "Making full-screen window non opaque is not supported.");
3855 }
3856 if (!gc.isTranslucencyCapable()) {
3857 GraphicsConfiguration capableGC = gd.getTranslucencyCapableGC();
3858 if (capableGC == null) {
3859 throw new UnsupportedOperationException(
3860 "PERPIXEL_TRANSLUCENT translucency is not supported");
3861 }
3862 setGraphicsConfiguration(capableGC);
3863 }
3864 setLayersOpaque(this, false);
3865 } else if ((oldAlpha < 255) && (alpha == 255)) {
3866 setLayersOpaque(this, true);
3867 }
3868 WindowPeer peer = (WindowPeer) this.peer;
3869 if (peer != null) {
3870 peer.setOpaque(alpha == 255);
3871 }
3872 }
3873
3874 /**
3875 * Indicates if the window is currently opaque.
3876 * <p>
3877 * The method returns {@code false} if the background color of the window
3878 * is not {@code null} and the alpha component of the color is less than
3879 * {@code 1.0f}. The method returns {@code true} otherwise.
3880 *
3881 * @return {@code true} if the window is opaque, {@code false} otherwise
3882 *
3883 * @see Window#getBackground
3884 * @see Window#setBackground(Color)
3885 * @since 1.7
3886 */
3887 @Override
3888 public boolean isOpaque() {
3889 Color bg = getBackground();
3890 return bg != null ? bg.getAlpha() == 255 : true;
3891 }
3892
3893 private void updateWindow() {
3894 synchronized (getTreeLock()) {
3895 WindowPeer peer = (WindowPeer) this.peer;
3896 if (peer != null) {
3897 peer.updateWindow();
3898 }
3899 }
3900 }
3901
3902 /**
3903 * {@inheritDoc}
3904 *
3905 * @since 1.7
3906 */
3907 @Override
3908 public void paint(Graphics g) {
3909 if (!isOpaque()) {
3910 Graphics gg = g.create();
3911 try {
3912 if (gg instanceof Graphics2D) {
3913 gg.setColor(getBackground());
3914 ((Graphics2D)gg).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));
3915 gg.fillRect(0, 0, getWidth(), getHeight());
4063 bg = new Color(0, 0, 0, 0);
4064 }
4065 window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
4066 opaque ? 255 : 0));
4067 }
4068 public void updateWindow(Window window) {
4069 window.updateWindow();
4070 }
4071
4072 public Dimension getSecurityWarningSize(Window window) {
4073 return new Dimension(window.securityWarningWidth,
4074 window.securityWarningHeight);
4075 }
4076
4077 public void setSecurityWarningSize(Window window, int width, int height)
4078 {
4079 window.securityWarningWidth = width;
4080 window.securityWarningHeight = height;
4081 }
4082
4083 public void setSecurityWarningPosition(Window window,
4084 Point2D point, float alignmentX, float alignmentY)
4085 {
4086 window.securityWarningPointX = point.getX();
4087 window.securityWarningPointY = point.getY();
4088 window.securityWarningAlignmentX = alignmentX;
4089 window.securityWarningAlignmentY = alignmentY;
4090
4091 synchronized (window.getTreeLock()) {
4092 WindowPeer peer = (WindowPeer) window.peer;
4093 if (peer != null) {
4094 peer.repositionSecurityWarning();
4095 }
4096 }
4097 }
4098
4099 public Point2D calculateSecurityWarningPosition(Window window,
4100 double x, double y, double w, double h)
4101 {
4102 return window.calculateSecurityWarningPosition(x, y, w, h);
4103 }
4104
4105 public void setLWRequestStatus(Window changed, boolean status) {
4106 changed.syncLWRequests = status;
4107 }
4108
4109 public boolean isAutoRequestFocus(Window w) {
4110 return w.autoRequestFocus;
4111 }
4112
|