Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/sun/awt/EmbeddedFrame.java
41152 views
1
/*
2
* Copyright (c) 1996, 2021, 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 sun.awt;
27
28
import java.applet.Applet;
29
import java.awt.AWTKeyStroke;
30
import java.awt.Component;
31
import java.awt.Container;
32
import java.awt.Cursor;
33
import java.awt.Dialog;
34
import java.awt.Dimension;
35
import java.awt.Frame;
36
import java.awt.Image;
37
import java.awt.KeyEventDispatcher;
38
import java.awt.KeyboardFocusManager;
39
import java.awt.MenuBar;
40
import java.awt.MenuComponent;
41
import java.awt.Point;
42
import java.awt.Rectangle;
43
import java.awt.event.KeyEvent;
44
import java.awt.peer.ComponentPeer;
45
import java.awt.peer.FramePeer;
46
import java.beans.PropertyChangeEvent;
47
import java.beans.PropertyChangeListener;
48
import java.io.Serial;
49
import java.util.Set;
50
51
/**
52
* A generic container used for embedding Java components, usually applets.
53
* An EmbeddedFrame has two related uses:
54
*
55
* . Within a Java-based application, an EmbeddedFrame serves as a sort of
56
* firewall, preventing the contained components or applets from using
57
* getParent() to find parent components, such as menubars.
58
*
59
* . Within a C-based application, an EmbeddedFrame contains a window handle
60
* which was created by the application, which serves as the top-level
61
* Java window. EmbeddedFrames created for this purpose are passed-in a
62
* handle of an existing window created by the application. The window
63
* handle should be of the appropriate native type for a specific
64
* platform, as stored in the pData field of the ComponentPeer.
65
*
66
* @author Thomas Ball
67
*/
68
public abstract class EmbeddedFrame extends Frame
69
implements KeyEventDispatcher, PropertyChangeListener {
70
71
private boolean isCursorAllowed = true;
72
private boolean supportsXEmbed = false;
73
@SuppressWarnings("serial") // Not statically typed as Serializable
74
private KeyboardFocusManager appletKFM;
75
76
/**
77
* Use serialVersionUID from JDK 1.1 for interoperability.
78
*/
79
@Serial
80
private static final long serialVersionUID = 2967042741780317130L;
81
82
/*
83
* The constants define focus traversal directions.
84
* Use them in {@code traverseIn}, {@code traverseOut} methods.
85
*/
86
protected static final boolean FORWARD = true;
87
protected static final boolean BACKWARD = false;
88
89
public boolean supportsXEmbed() {
90
return supportsXEmbed && SunToolkit.needsXEmbed();
91
}
92
93
protected EmbeddedFrame(boolean supportsXEmbed) {
94
this((long)0, supportsXEmbed);
95
}
96
97
98
protected EmbeddedFrame() {
99
this((long)0);
100
}
101
102
/**
103
* @deprecated This constructor will be removed in 1.5
104
*/
105
@Deprecated
106
protected EmbeddedFrame(int handle) {
107
this((long)handle);
108
}
109
110
protected EmbeddedFrame(long handle) {
111
this(handle, false);
112
}
113
114
protected EmbeddedFrame(long handle, boolean supportsXEmbed) {
115
this.supportsXEmbed = supportsXEmbed;
116
registerListeners();
117
}
118
119
/**
120
* Block introspection of a parent window by this child.
121
*/
122
public Container getParent() {
123
return null;
124
}
125
126
/**
127
* Needed to track which KeyboardFocusManager is current. We want to avoid memory
128
* leaks, so when KFM stops being current, we remove ourselves as listeners.
129
*/
130
public void propertyChange(PropertyChangeEvent evt) {
131
// We don't handle any other properties. Skip it.
132
if (!evt.getPropertyName().equals("managingFocus")) {
133
return;
134
}
135
136
// We only do it if it stops being current. Technically, we should
137
// never get an event about KFM starting being current.
138
if (evt.getNewValue() == Boolean.TRUE) {
139
return;
140
}
141
142
// should be the same as appletKFM
143
removeTraversingOutListeners((KeyboardFocusManager)evt.getSource());
144
145
appletKFM = KeyboardFocusManager.getCurrentKeyboardFocusManager();
146
if (isVisible()) {
147
addTraversingOutListeners(appletKFM);
148
}
149
}
150
151
/**
152
* Register us as KeyEventDispatcher and property "managingFocus" listeners.
153
*/
154
private void addTraversingOutListeners(KeyboardFocusManager kfm) {
155
kfm.addKeyEventDispatcher(this);
156
kfm.addPropertyChangeListener("managingFocus", this);
157
}
158
159
/**
160
* Deregister us as KeyEventDispatcher and property "managingFocus" listeners.
161
*/
162
private void removeTraversingOutListeners(KeyboardFocusManager kfm) {
163
kfm.removeKeyEventDispatcher(this);
164
kfm.removePropertyChangeListener("managingFocus", this);
165
}
166
167
/**
168
* Because there may be many AppContexts, and we can't be sure where this
169
* EmbeddedFrame is first created or shown, we can't automatically determine
170
* the correct KeyboardFocusManager to attach to as KeyEventDispatcher.
171
* Those who want to use the functionality of traversing out of the EmbeddedFrame
172
* must call this method on the Applet's AppContext. After that, all the changes
173
* can be handled automatically, including possible replacement of
174
* KeyboardFocusManager.
175
*/
176
public void registerListeners() {
177
if (appletKFM != null) {
178
removeTraversingOutListeners(appletKFM);
179
}
180
appletKFM = KeyboardFocusManager.getCurrentKeyboardFocusManager();
181
if (isVisible()) {
182
addTraversingOutListeners(appletKFM);
183
}
184
}
185
186
/**
187
* Needed to avoid memory leak: we register this EmbeddedFrame as a listener with
188
* KeyboardFocusManager of applet's AppContext. We don't want the KFM to keep
189
* reference to our EmbeddedFrame forever if the Frame is no longer in use, so we
190
* add listeners in show() and remove them in hide().
191
*/
192
@SuppressWarnings("deprecation")
193
public void show() {
194
if (appletKFM != null) {
195
addTraversingOutListeners(appletKFM);
196
}
197
super.show();
198
}
199
200
/**
201
* Needed to avoid memory leak: we register this EmbeddedFrame as a listener with
202
* KeyboardFocusManager of applet's AppContext. We don't want the KFM to keep
203
* reference to our EmbeddedFrame forever if the Frame is no longer in use, so we
204
* add listeners in show() and remove them in hide().
205
*/
206
@SuppressWarnings("deprecation")
207
public void hide() {
208
if (appletKFM != null) {
209
removeTraversingOutListeners(appletKFM);
210
}
211
super.hide();
212
}
213
214
/**
215
* Need this method to detect when the focus may have chance to leave the
216
* focus cycle root which is EmbeddedFrame. Mostly, the code here is copied
217
* from DefaultKeyboardFocusManager.processKeyEvent with some minor
218
* modifications.
219
*/
220
public boolean dispatchKeyEvent(KeyEvent e) {
221
222
Container currentRoot = AWTAccessor.getKeyboardFocusManagerAccessor()
223
.getCurrentFocusCycleRoot();
224
225
// if we are not in EmbeddedFrame's cycle, we should not try to leave.
226
if (this != currentRoot) {
227
return false;
228
}
229
230
// KEY_TYPED events cannot be focus traversal keys
231
if (e.getID() == KeyEvent.KEY_TYPED) {
232
return false;
233
}
234
235
if (!getFocusTraversalKeysEnabled() || e.isConsumed()) {
236
return false;
237
}
238
239
AWTKeyStroke stroke = AWTKeyStroke.getAWTKeyStrokeForEvent(e);
240
Set<AWTKeyStroke> toTest;
241
Component currentFocused = e.getComponent();
242
243
toTest = getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
244
if (toTest.contains(stroke)) {
245
// 6581899: performance improvement for SortingFocusTraversalPolicy
246
Component last = getFocusTraversalPolicy().getLastComponent(this);
247
if (currentFocused == last || last == null) {
248
if (traverseOut(FORWARD)) {
249
e.consume();
250
return true;
251
}
252
}
253
}
254
255
toTest = getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
256
if (toTest.contains(stroke)) {
257
// 6581899: performance improvement for SortingFocusTraversalPolicy
258
Component first = getFocusTraversalPolicy().getFirstComponent(this);
259
if (currentFocused == first || first == null) {
260
if (traverseOut(BACKWARD)) {
261
e.consume();
262
return true;
263
}
264
}
265
}
266
return false;
267
}
268
269
/**
270
* This method is called by the embedder when we should receive focus as element
271
* of the traversal chain. The method requests focus on:
272
* 1. the first Component of this EmbeddedFrame if user moves focus forward
273
* in the focus traversal cycle.
274
* 2. the last Component of this EmbeddedFrame if user moves focus backward
275
* in the focus traversal cycle.
276
*
277
* The direction parameter specifies which of the two mentioned cases is
278
* happening. Use FORWARD and BACKWARD constants defined in the EmbeddedFrame class
279
* to avoid confusing boolean values.
280
*
281
* A concrete implementation of this method is defined in the platform-dependent
282
* subclasses.
283
*
284
* @param direction FORWARD or BACKWARD
285
* @return true, if the EmbeddedFrame wants to get focus, false otherwise.
286
*/
287
public boolean traverseIn(boolean direction) {
288
Component comp = null;
289
290
if (direction == FORWARD) {
291
comp = getFocusTraversalPolicy().getFirstComponent(this);
292
} else {
293
comp = getFocusTraversalPolicy().getLastComponent(this);
294
}
295
if (comp != null) {
296
// comp.requestFocus(); - Leads to a hung.
297
298
AWTAccessor.getKeyboardFocusManagerAccessor().setMostRecentFocusOwner(this, comp);
299
synthesizeWindowActivation(true);
300
}
301
return (null != comp);
302
}
303
304
/**
305
* This method is called from dispatchKeyEvent in the following two cases:
306
* 1. The focus is on the first Component of this EmbeddedFrame and we are
307
* about to transfer the focus backward.
308
* 2. The focus in on the last Component of this EmbeddedFrame and we are
309
* about to transfer the focus forward.
310
* This is needed to give the opportuity for keyboard focus to leave the
311
* EmbeddedFrame. Override this method, initiate focus transfer in it and
312
* return true if you want the focus to leave EmbeddedFrame's cycle.
313
* The direction parameter specifies which of the two mentioned cases is
314
* happening. Use FORWARD and BACKWARD constants defined in EmbeddedFrame
315
* to avoid confusing boolean values.
316
*
317
* @param direction FORWARD or BACKWARD
318
* @return true, if EmbeddedFrame wants the focus to leave it,
319
* false otherwise.
320
*/
321
protected boolean traverseOut(boolean direction) {
322
return false;
323
}
324
325
/**
326
* Block modifying any frame attributes, since they aren't applicable
327
* for EmbeddedFrames.
328
*/
329
public void setTitle(String title) {}
330
public void setIconImage(Image image) {}
331
public void setIconImages(java.util.List<? extends Image> icons) {}
332
public void setMenuBar(MenuBar mb) {}
333
public void setResizable(boolean resizable) {}
334
public void remove(MenuComponent m) {}
335
336
public boolean isResizable() {
337
return true;
338
}
339
340
public void addNotify() {
341
synchronized (getTreeLock()) {
342
if (!isDisplayable()) {
343
setPeer(new NullEmbeddedFramePeer());
344
}
345
super.addNotify();
346
}
347
}
348
349
// These three functions consitute RFE 4100710. Do not remove.
350
public void setCursorAllowed(boolean isCursorAllowed) {
351
this.isCursorAllowed = isCursorAllowed;
352
final FramePeer peer = AWTAccessor.getComponentAccessor().getPeer(this);
353
peer.updateCursorImmediately();
354
}
355
public boolean isCursorAllowed() {
356
return isCursorAllowed;
357
}
358
public Cursor getCursor() {
359
return (isCursorAllowed)
360
? super.getCursor()
361
: Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
362
}
363
364
protected void setPeer(final ComponentPeer p){
365
AWTAccessor.getComponentAccessor().setPeer(EmbeddedFrame.this, p);
366
};
367
368
/**
369
* Synthesize native message to activate or deactivate EmbeddedFrame window
370
* depending on the value of parameter {@code b}.
371
* Peers should override this method if they are to implement
372
* this functionality.
373
* @param doActivate if {@code true}, activates the window;
374
* otherwise, deactivates the window
375
*/
376
public void synthesizeWindowActivation(boolean doActivate) {}
377
378
/**
379
* Moves this embedded frame to a new location. The top-left corner of
380
* the new location is specified by the {@code x} and {@code y}
381
* parameters relative to the native parent component.
382
* <p>
383
* setLocation() and setBounds() for EmbeddedFrame really don't move it
384
* within the native parent. These methods always put embedded frame to
385
* (0, 0) for backward compatibility. To allow moving embedded frame
386
* setLocationPrivate() and setBoundsPrivate() were introduced, and they
387
* work just the same way as setLocation() and setBounds() for usual,
388
* non-embedded components.
389
* </p>
390
* <p>
391
* Using usual get/setLocation() and get/setBounds() together with new
392
* get/setLocationPrivate() and get/setBoundsPrivate() is not recommended.
393
* For example, calling getBoundsPrivate() after setLocation() works fine,
394
* but getBounds() after setBoundsPrivate() may return unpredictable value.
395
* </p>
396
* @param x the new <i>x</i>-coordinate relative to the parent component
397
* @param y the new <i>y</i>-coordinate relative to the parent component
398
* @see java.awt.Component#setLocation
399
* @see #getLocationPrivate
400
* @see #setBoundsPrivate
401
* @see #getBoundsPrivate
402
* @since 1.5
403
*/
404
protected void setLocationPrivate(int x, int y) {
405
Dimension size = getSize();
406
setBoundsPrivate(x, y, size.width, size.height);
407
}
408
409
/**
410
* Gets the location of this embedded frame as a point specifying the
411
* top-left corner relative to parent component.
412
* <p>
413
* setLocation() and setBounds() for EmbeddedFrame really don't move it
414
* within the native parent. These methods always put embedded frame to
415
* (0, 0) for backward compatibility. To allow getting location and size
416
* of embedded frame getLocationPrivate() and getBoundsPrivate() were
417
* introduced, and they work just the same way as getLocation() and getBounds()
418
* for ususal, non-embedded components.
419
* </p>
420
* <p>
421
* Using usual get/setLocation() and get/setBounds() together with new
422
* get/setLocationPrivate() and get/setBoundsPrivate() is not recommended.
423
* For example, calling getBoundsPrivate() after setLocation() works fine,
424
* but getBounds() after setBoundsPrivate() may return unpredictable value.
425
* </p>
426
* @return a point indicating this embedded frame's top-left corner
427
* @see java.awt.Component#getLocation
428
* @see #setLocationPrivate
429
* @see #setBoundsPrivate
430
* @see #getBoundsPrivate
431
* @since 1.6
432
*/
433
protected Point getLocationPrivate() {
434
Rectangle bounds = getBoundsPrivate();
435
return new Point(bounds.x, bounds.y);
436
}
437
438
/**
439
* Moves and resizes this embedded frame. The new location of the top-left
440
* corner is specified by {@code x} and {@code y} parameters
441
* relative to the native parent component. The new size is specified by
442
* {@code width} and {@code height}.
443
* <p>
444
* setLocation() and setBounds() for EmbeddedFrame really don't move it
445
* within the native parent. These methods always put embedded frame to
446
* (0, 0) for backward compatibility. To allow moving embedded frames
447
* setLocationPrivate() and setBoundsPrivate() were introduced, and they
448
* work just the same way as setLocation() and setBounds() for usual,
449
* non-embedded components.
450
* </p>
451
* <p>
452
* Using usual get/setLocation() and get/setBounds() together with new
453
* get/setLocationPrivate() and get/setBoundsPrivate() is not recommended.
454
* For example, calling getBoundsPrivate() after setLocation() works fine,
455
* but getBounds() after setBoundsPrivate() may return unpredictable value.
456
* </p>
457
* @param x the new <i>x</i>-coordinate relative to the parent component
458
* @param y the new <i>y</i>-coordinate relative to the parent component
459
* @param width the new {@code width} of this embedded frame
460
* @param height the new {@code height} of this embedded frame
461
* @see java.awt.Component#setBounds
462
* @see #setLocationPrivate
463
* @see #getLocationPrivate
464
* @see #getBoundsPrivate
465
* @since 1.5
466
*/
467
protected void setBoundsPrivate(int x, int y, int width, int height) {
468
final FramePeer peer = AWTAccessor.getComponentAccessor().getPeer(this);
469
if (peer != null) {
470
peer.setBoundsPrivate(x, y, width, height);
471
}
472
}
473
474
/**
475
* Gets the bounds of this embedded frame as a rectangle specifying the
476
* width, height and location relative to the native parent component.
477
* <p>
478
* setLocation() and setBounds() for EmbeddedFrame really don't move it
479
* within the native parent. These methods always put embedded frame to
480
* (0, 0) for backward compatibility. To allow getting location and size
481
* of embedded frames getLocationPrivate() and getBoundsPrivate() were
482
* introduced, and they work just the same way as getLocation() and getBounds()
483
* for ususal, non-embedded components.
484
* </p>
485
* <p>
486
* Using usual get/setLocation() and get/setBounds() together with new
487
* get/setLocationPrivate() and get/setBoundsPrivate() is not recommended.
488
* For example, calling getBoundsPrivate() after setLocation() works fine,
489
* but getBounds() after setBoundsPrivate() may return unpredictable value.
490
* </p>
491
* @return a rectangle indicating this embedded frame's bounds
492
* @see java.awt.Component#getBounds
493
* @see #setLocationPrivate
494
* @see #getLocationPrivate
495
* @see #setBoundsPrivate
496
* @since 1.6
497
*/
498
protected Rectangle getBoundsPrivate() {
499
final FramePeer peer = AWTAccessor.getComponentAccessor().getPeer(this);
500
if (peer != null) {
501
return peer.getBoundsPrivate();
502
}
503
else {
504
return getBounds();
505
}
506
}
507
508
public void toFront() {}
509
public void toBack() {}
510
511
public abstract void registerAccelerator(AWTKeyStroke stroke);
512
public abstract void unregisterAccelerator(AWTKeyStroke stroke);
513
514
/**
515
* Checks if the component is in an EmbeddedFrame. If so,
516
* returns the applet found in the hierarchy or null if
517
* not found.
518
* @return the parent applet or {@code null}
519
* @since 1.6
520
*
521
* @deprecated The Applet API is deprecated. See the
522
* <a href="../../java/applet/package-summary.html"> java.applet package
523
* documentation</a> for further information.
524
*/
525
@Deprecated(since = "9", forRemoval = true)
526
@SuppressWarnings("removal")
527
public static Applet getAppletIfAncestorOf(Component comp) {
528
Container parent = comp.getParent();
529
Applet applet = null;
530
while (parent != null && !(parent instanceof EmbeddedFrame)) {
531
if (parent instanceof Applet) {
532
applet = (Applet)parent;
533
}
534
parent = parent.getParent();
535
}
536
return parent == null ? null : applet;
537
}
538
539
/**
540
* This method should be overriden in subclasses. It is
541
* called when window this frame is within should be blocked
542
* by some modal dialog.
543
*/
544
public void notifyModalBlocked(Dialog blocker, boolean blocked) {
545
}
546
547
private static class NullEmbeddedFramePeer
548
extends NullComponentPeer implements FramePeer {
549
public void setTitle(String title) {}
550
public void setIconImage(Image im) {}
551
public void updateIconImages() {}
552
public void setMenuBar(MenuBar mb) {}
553
public void setResizable(boolean resizeable) {}
554
public void setState(int state) {}
555
public int getState() { return Frame.NORMAL; }
556
public void setMaximizedBounds(Rectangle b) {}
557
public void toFront() {}
558
public void toBack() {}
559
public void updateFocusableWindowState() {}
560
public void updateAlwaysOnTop() {}
561
public void updateAlwaysOnTopState() {}
562
public Component getGlobalHeavyweightFocusOwner() { return null; }
563
public void setBoundsPrivate(int x, int y, int width, int height) {
564
setBounds(x, y, width, height, SET_BOUNDS);
565
}
566
public Rectangle getBoundsPrivate() {
567
return getBounds();
568
}
569
public void setModalBlocked(Dialog blocker, boolean blocked) {}
570
571
public void restack() {
572
throw new UnsupportedOperationException();
573
}
574
575
public boolean isRestackSupported() {
576
return false;
577
}
578
public boolean requestWindowFocus() {
579
return false;
580
}
581
public void updateMinimumSize() {
582
}
583
584
public void setOpacity(float opacity) {
585
}
586
587
public void setOpaque(boolean isOpaque) {
588
}
589
590
public void updateWindow() {
591
}
592
593
public void repositionSecurityWarning() {
594
}
595
596
public void emulateActivation(boolean activate) {
597
}
598
}
599
} // class EmbeddedFrame
600
601