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