Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameUI.java
41154 views
1
/*
2
* Copyright (c) 2011, 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 com.apple.laf;
27
28
import java.awt.*;
29
import java.awt.event.*;
30
import java.beans.*;
31
32
import javax.swing.*;
33
import javax.swing.border.*;
34
import javax.swing.event.MouseInputAdapter;
35
import javax.swing.plaf.*;
36
import javax.swing.plaf.basic.BasicInternalFrameUI;
37
38
import apple.laf.*;
39
import apple.laf.JRSUIConstants.*;
40
41
import com.apple.laf.AquaUtils.*;
42
import com.apple.laf.AquaUtils.Painter;
43
44
import sun.lwawt.macosx.CPlatformWindow;
45
46
/**
47
* From AquaInternalFrameUI
48
*
49
* InternalFrame implementation for Aqua LAF
50
*
51
* We want to inherit most of the inner classes, but not the base class,
52
* so be very careful about subclassing so you know you get what you want
53
*
54
*/
55
public class AquaInternalFrameUI extends BasicInternalFrameUI implements SwingConstants {
56
protected static final String IS_PALETTE_PROPERTY = "JInternalFrame.isPalette";
57
private static final String FRAME_TYPE = "JInternalFrame.frameType";
58
private static final String NORMAL_FRAME = "normal";
59
private static final String PALETTE_FRAME = "palette";
60
private static final String OPTION_DIALOG = "optionDialog";
61
62
// Instance variables
63
PropertyChangeListener fPropertyListener;
64
65
protected Color fSelectedTextColor;
66
protected Color fNotSelectedTextColor;
67
68
AquaInternalFrameBorder fAquaBorder;
69
private ResizeBox resizeBox;
70
71
// for button tracking
72
boolean fMouseOverPressedButton;
73
int fWhichButtonPressed = -1;
74
boolean fRollover = false;
75
boolean fDocumentEdited = false; // to indicate whether we should use the dirty document red dot.
76
boolean fIsPallet;
77
78
public int getWhichButtonPressed() {
79
return fWhichButtonPressed;
80
}
81
82
public boolean getMouseOverPressedButton() {
83
return fMouseOverPressedButton;
84
}
85
86
public boolean getRollover() {
87
return fRollover;
88
}
89
90
// ComponentUI Interface Implementation methods
91
public static ComponentUI createUI(final JComponent b) {
92
return new AquaInternalFrameUI((JInternalFrame)b);
93
}
94
95
public AquaInternalFrameUI(final JInternalFrame b) {
96
super(b);
97
}
98
99
/// Inherit (but be careful to check everything they call):
100
@Override
101
public void installUI(final JComponent c) {
102
// super.installUI(c); // Swing 1.1.1 has a bug in installUI - it doesn't check for null northPane
103
frame = (JInternalFrame)c;
104
frame.add(frame.getRootPane(), "Center");
105
106
installDefaults();
107
installListeners();
108
installComponents();
109
installKeyboardActions();
110
111
Object paletteProp = c.getClientProperty(IS_PALETTE_PROPERTY);
112
if (paletteProp != null) {
113
setPalette(((Boolean)paletteProp).booleanValue());
114
} else {
115
paletteProp = c.getClientProperty(FRAME_TYPE);
116
if (paletteProp != null) {
117
setFrameType((String)paletteProp);
118
} else {
119
setFrameType(NORMAL_FRAME);
120
}
121
}
122
123
// We only have a southPane, for grow box room, created in setFrameType
124
frame.setMinimumSize(new Dimension(fIsPallet ? 120 : 150, fIsPallet ? 39 : 65));
125
frame.setOpaque(false);
126
127
c.setBorder(new CompoundUIBorder(fIsPallet ? paletteWindowShadow.get() : documentWindowShadow.get(), c.getBorder()));
128
}
129
130
@Override
131
protected void installDefaults() {
132
super.installDefaults();
133
fSelectedTextColor = UIManager.getColor("InternalFrame.activeTitleForeground");
134
fNotSelectedTextColor = UIManager.getColor("InternalFrame.inactiveTitleForeground");
135
}
136
137
@Override
138
public void setSouthPane(final JComponent c) {
139
if (southPane != null) {
140
frame.remove(southPane);
141
deinstallMouseHandlers(southPane);
142
}
143
if (c != null) {
144
frame.add(c);
145
installMouseHandlers(c);
146
}
147
southPane = c;
148
}
149
150
private static final RecyclableSingleton<Icon> closeIcon = new RecyclableSingleton<Icon>() {
151
@Override
152
protected Icon getInstance() {
153
return new AquaInternalFrameButtonIcon(Widget.TITLE_BAR_CLOSE_BOX);
154
}
155
};
156
public static Icon exportCloseIcon() {
157
return closeIcon.get();
158
}
159
160
private static final RecyclableSingleton<Icon> minimizeIcon = new RecyclableSingleton<Icon>() {
161
@Override
162
protected Icon getInstance() {
163
return new AquaInternalFrameButtonIcon(Widget.TITLE_BAR_COLLAPSE_BOX);
164
}
165
};
166
public static Icon exportMinimizeIcon() {
167
return minimizeIcon.get();
168
}
169
170
private static final RecyclableSingleton<Icon> zoomIcon = new RecyclableSingleton<Icon>() {
171
@Override
172
protected Icon getInstance() {
173
return new AquaInternalFrameButtonIcon(Widget.TITLE_BAR_ZOOM_BOX);
174
}
175
};
176
public static Icon exportZoomIcon() {
177
return zoomIcon.get();
178
}
179
180
static class AquaInternalFrameButtonIcon extends AquaIcon.JRSUIIcon {
181
public AquaInternalFrameButtonIcon(final Widget widget) {
182
painter.state.set(widget);
183
}
184
185
@Override
186
public void paintIcon(final Component c, final Graphics g, final int x, final int y) {
187
painter.state.set(getStateFor(c));
188
super.paintIcon(c, g, x, y);
189
}
190
191
State getStateFor(final Component c) {
192
return State.ROLLOVER;
193
}
194
195
@Override
196
public int getIconWidth() {
197
return 19;
198
}
199
200
@Override
201
public int getIconHeight() {
202
return 19;
203
}
204
}
205
206
@Override
207
protected void installKeyboardActions() {
208
} //$ Not Mac-ish - should we support?
209
210
@Override
211
protected void installComponents() {
212
final JLayeredPane layeredPane = frame.getLayeredPane();
213
resizeBox = new ResizeBox(layeredPane);
214
resizeBox.repositionResizeBox();
215
216
layeredPane.add(resizeBox);
217
layeredPane.setLayer(resizeBox, JLayeredPane.DRAG_LAYER);
218
layeredPane.addComponentListener(resizeBox);
219
220
resizeBox.addListeners();
221
resizeBox.setVisible(frame.isResizable());
222
}
223
224
/// Inherit all the listeners - that's the main reason we subclass Basic!
225
@Override
226
protected void installListeners() {
227
fPropertyListener = new PropertyListener();
228
frame.addPropertyChangeListener(fPropertyListener);
229
super.installListeners();
230
}
231
232
// uninstallDefaults
233
234
@Override
235
protected void uninstallComponents() {
236
super.uninstallComponents();
237
final JLayeredPane layeredPane = frame.getLayeredPane();
238
resizeBox.removeListeners();
239
layeredPane.removeComponentListener(resizeBox);
240
layeredPane.remove(resizeBox);
241
resizeBox = null;
242
}
243
244
@Override
245
protected void uninstallListeners() {
246
super.uninstallListeners();
247
frame.removePropertyChangeListener(fPropertyListener);
248
}
249
250
@Override
251
protected void uninstallKeyboardActions() {
252
}
253
254
// Called when a DesktopIcon replaces an InternalFrame & vice versa
255
//protected void replacePane(JComponent currentPane, JComponent newPane) {}
256
@Override
257
protected void installMouseHandlers(final JComponent c) {
258
c.addMouseListener(borderListener);
259
c.addMouseMotionListener(borderListener);
260
}
261
262
@Override
263
protected void deinstallMouseHandlers(final JComponent c) {
264
c.removeMouseListener(borderListener);
265
c.removeMouseMotionListener(borderListener);
266
}
267
268
ActionMap createActionMap() {
269
final ActionMap map = new ActionMapUIResource();
270
// add action for the system menu
271
// Set the ActionMap's parent to the Auditory Feedback Action Map
272
final AquaLookAndFeel lf = (AquaLookAndFeel)UIManager.getLookAndFeel();
273
final ActionMap audioMap = lf.getAudioActionMap();
274
map.setParent(audioMap);
275
return map;
276
}
277
278
@Override
279
public Dimension getPreferredSize(JComponent x) {
280
Dimension preferredSize = super.getPreferredSize(x);
281
Dimension minimumSize = frame.getMinimumSize();
282
if (preferredSize.width < minimumSize.width) {
283
preferredSize.width = minimumSize.width;
284
}
285
if (preferredSize.height < minimumSize.height) {
286
preferredSize.height = minimumSize.height;
287
}
288
return preferredSize;
289
}
290
291
@Override
292
public void setNorthPane(final JComponent c) {
293
replacePane(northPane, c);
294
northPane = c;
295
}
296
297
/**
298
* Installs necessary mouse handlers on {@code newPane}
299
* and adds it to the frame.
300
* Reverse process for the {@code currentPane}.
301
*/
302
@Override
303
protected void replacePane(final JComponent currentPane, final JComponent newPane) {
304
if (currentPane != null) {
305
deinstallMouseHandlers(currentPane);
306
frame.remove(currentPane);
307
}
308
if (newPane != null) {
309
frame.add(newPane);
310
installMouseHandlers(newPane);
311
}
312
}
313
314
// Our "Border" listener is shared by the AquaDesktopIcon
315
@Override
316
protected MouseInputAdapter createBorderListener(final JInternalFrame w) {
317
return new AquaBorderListener();
318
}
319
320
/**
321
* Mac-specific stuff begins here
322
*/
323
void setFrameType(final String frameType) {
324
// Basic sets the background of the contentPane to null so it can inherit JInternalFrame.setBackground
325
// but if *that's* null, we get the JDesktop, which makes ours look invisible!
326
// So JInternalFrame has to have a background color
327
// See Sun bugs 4268949 & 4320889
328
final Color bg = frame.getBackground();
329
final boolean replaceColor = (bg == null || bg instanceof UIResource);
330
331
final Font font = frame.getFont();
332
final boolean replaceFont = (font == null || font instanceof UIResource);
333
334
boolean isPalette = false;
335
if (frameType.equals(OPTION_DIALOG)) {
336
fAquaBorder = AquaInternalFrameBorder.dialog();
337
if (replaceColor) frame.setBackground(UIManager.getColor("InternalFrame.optionDialogBackground"));
338
if (replaceFont) frame.setFont(UIManager.getFont("InternalFrame.optionDialogTitleFont"));
339
} else if (frameType.equals(PALETTE_FRAME)) {
340
fAquaBorder = AquaInternalFrameBorder.utility();
341
if (replaceColor) frame.setBackground(UIManager.getColor("InternalFrame.paletteBackground"));
342
if (replaceFont) frame.setFont(UIManager.getFont("InternalFrame.paletteTitleFont"));
343
isPalette = true;
344
} else {
345
fAquaBorder = AquaInternalFrameBorder.window();
346
if (replaceColor) frame.setBackground(UIManager.getColor("InternalFrame.background"));
347
if (replaceFont) frame.setFont(UIManager.getFont("InternalFrame.titleFont"));
348
}
349
// We don't get the borders from UIManager, in case someone changes them - this class will not work with
350
// different borders. If they want different ones, they have to make their own InternalFrameUI class
351
352
fAquaBorder.setColors(fSelectedTextColor, fNotSelectedTextColor);
353
frame.setBorder(fAquaBorder);
354
355
fIsPallet = isPalette;
356
}
357
358
public void setPalette(final boolean isPalette) {
359
setFrameType(isPalette ? PALETTE_FRAME : NORMAL_FRAME);
360
}
361
362
public boolean isDocumentEdited() {
363
return fDocumentEdited;
364
}
365
366
public void setDocumentEdited(final boolean flag) {
367
fDocumentEdited = flag;
368
}
369
370
/*
371
// helpful debug drawing, shows component and content bounds
372
public void paint(final Graphics g, final JComponent c) {
373
super.paint(g, c);
374
375
g.setColor(Color.green);
376
g.drawRect(0, 0, frame.getWidth() - 1, frame.getHeight() - 1);
377
378
final Insets insets = frame.getInsets();
379
g.setColor(Color.orange);
380
g.drawRect(insets.left - 2, insets.top - 2, frame.getWidth() - insets.left - insets.right + 4, frame.getHeight() - insets.top - insets.bottom + 4);
381
}
382
*/
383
384
// Border Listener Class
385
/**
386
* Listens for border adjustments.
387
*/
388
protected class AquaBorderListener extends MouseInputAdapter {
389
// _x & _y are the mousePressed location in absolute coordinate system
390
int _x, _y;
391
// __x & __y are the mousePressed location in source view's coordinate system
392
int __x, __y;
393
Rectangle startingBounds;
394
boolean fDraggingFrame;
395
int resizeDir;
396
397
protected final int RESIZE_NONE = 0;
398
private boolean discardRelease = false;
399
400
@Override
401
public void mouseClicked(final MouseEvent e) {
402
if (didForwardEvent(e)) return;
403
404
if (e.getClickCount() <= 1 || e.getSource() != getNorthPane()) return;
405
406
if (frame.isIconifiable() && frame.isIcon()) {
407
try {
408
frame.setIcon(false);
409
} catch(final PropertyVetoException e2) {}
410
} else if (frame.isMaximizable()) {
411
if (!frame.isMaximum()) try {
412
frame.setMaximum(true);
413
} catch(final PropertyVetoException e2) {}
414
else try {
415
frame.setMaximum(false);
416
} catch(final PropertyVetoException e3) {}
417
}
418
}
419
420
public void updateRollover(final MouseEvent e) {
421
final boolean oldRollover = fRollover;
422
final Insets i = frame.getInsets();
423
fRollover = (isTitleBarDraggableArea(e) && fAquaBorder.getWithinRolloverArea(i, e.getX(), e.getY()));
424
if (fRollover != oldRollover) {
425
repaintButtons();
426
}
427
}
428
429
public void repaintButtons() {
430
fAquaBorder.repaintButtonArea(frame);
431
}
432
433
@Override
434
@SuppressWarnings("removal")
435
public void mouseReleased(final MouseEvent e) {
436
if (didForwardEvent(e)) return;
437
438
fDraggingFrame = false;
439
440
if (fWhichButtonPressed != -1) {
441
final int newButton = fAquaBorder.getWhichButtonHit(frame, e.getX(), e.getY());
442
443
final int buttonPresed = fWhichButtonPressed;
444
fWhichButtonPressed = -1;
445
fMouseOverPressedButton = false;
446
447
if (buttonPresed == newButton) {
448
fMouseOverPressedButton = false;
449
fRollover = false; // not sure if this is needed?
450
451
fAquaBorder.doButtonAction(frame, buttonPresed);
452
}
453
454
updateRollover(e);
455
repaintButtons();
456
return;
457
}
458
459
if (discardRelease) {
460
discardRelease = false;
461
return;
462
}
463
if (resizeDir == RESIZE_NONE) getDesktopManager().endDraggingFrame(frame);
464
else {
465
final Container c = frame.getTopLevelAncestor();
466
if (c instanceof JFrame) {
467
((JFrame)frame.getTopLevelAncestor()).getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
468
469
((JFrame)frame.getTopLevelAncestor()).getGlassPane().setVisible(false);
470
} else if (c instanceof JApplet) {
471
((JApplet)c).getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
472
((JApplet)c).getGlassPane().setVisible(false);
473
} else if (c instanceof JWindow) {
474
((JWindow)c).getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
475
((JWindow)c).getGlassPane().setVisible(false);
476
} else if (c instanceof JDialog) {
477
((JDialog)c).getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
478
((JDialog)c).getGlassPane().setVisible(false);
479
}
480
getDesktopManager().endResizingFrame(frame);
481
}
482
_x = 0;
483
_y = 0;
484
__x = 0;
485
__y = 0;
486
startingBounds = null;
487
resizeDir = RESIZE_NONE;
488
}
489
490
@Override
491
public void mousePressed(final MouseEvent e) {
492
if (didForwardEvent(e)) return;
493
494
final Point p = SwingUtilities.convertPoint((Component)e.getSource(), e.getX(), e.getY(), null);
495
__x = e.getX();
496
__y = e.getY();
497
_x = p.x;
498
_y = p.y;
499
startingBounds = frame.getBounds();
500
resizeDir = RESIZE_NONE;
501
502
if (updatePressed(e)) { return; }
503
504
if (!frame.isSelected()) {
505
try {
506
frame.setSelected(true);
507
} catch(final PropertyVetoException e1) {}
508
}
509
510
if (isTitleBarDraggableArea(e)) {
511
getDesktopManager().beginDraggingFrame(frame);
512
fDraggingFrame = true;
513
return;
514
}
515
516
if (e.getSource() == getNorthPane()) {
517
getDesktopManager().beginDraggingFrame(frame);
518
return;
519
}
520
521
if (!frame.isResizable()) { return; }
522
523
if (e.getSource() == frame) {
524
discardRelease = true;
525
return;
526
}
527
}
528
529
// returns true if we have handled the pressed
530
public boolean updatePressed(final MouseEvent e) {
531
// get the component.
532
fWhichButtonPressed = getButtonHit(e);
533
fMouseOverPressedButton = true;
534
repaintButtons();
535
return (fWhichButtonPressed >= 0);
536
// e.getX(), e.getY()
537
}
538
539
public int getButtonHit(final MouseEvent e) {
540
return fAquaBorder.getWhichButtonHit(frame, e.getX(), e.getY());
541
}
542
543
public boolean isTitleBarDraggableArea(final MouseEvent e) {
544
if (e.getSource() != frame) return false;
545
546
final Point point = e.getPoint();
547
final Insets insets = frame.getInsets();
548
549
if (point.y < insets.top - fAquaBorder.getTitleHeight()) return false;
550
if (point.y > insets.top) return false;
551
if (point.x < insets.left) return false;
552
if (point.x > frame.getWidth() - insets.left - insets.right) return false;
553
554
return true;
555
}
556
557
@Override
558
@SuppressWarnings("deprecation")
559
public void mouseDragged(final MouseEvent e) {
560
// do not forward drags
561
// if (didForwardEvent(e)) return;
562
563
if (startingBounds == null) {
564
// (STEVE) Yucky work around for bug ID 4106552
565
return;
566
}
567
568
if (fWhichButtonPressed != -1) {
569
// track the button we started on.
570
final int newButton = getButtonHit(e);
571
fMouseOverPressedButton = (fWhichButtonPressed == newButton);
572
repaintButtons();
573
return;
574
}
575
576
final Point p = SwingUtilities.convertPoint((Component)e.getSource(), e.getX(), e.getY(), null);
577
final int deltaX = _x - p.x;
578
final int deltaY = _y - p.y;
579
int newX, newY;
580
581
// Handle a MOVE
582
if (!fDraggingFrame && e.getSource() != getNorthPane()) return;
583
584
if (frame.isMaximum() || ((e.getModifiers() & InputEvent.BUTTON1_MASK) != InputEvent.BUTTON1_MASK)) {
585
// don't allow moving of frames if maximixed or left mouse
586
// button was not used.
587
return;
588
}
589
590
final Dimension s = frame.getParent().getSize();
591
final int pWidth = s.width;
592
final int pHeight = s.height;
593
594
final Insets i = frame.getInsets();
595
newX = startingBounds.x - deltaX;
596
newY = startingBounds.y - deltaY;
597
598
// Make sure we stay in-bounds
599
if (newX + i.left <= -__x) newX = -__x - i.left;
600
if (newY + i.top <= -__y) newY = -__y - i.top;
601
if (newX + __x + i.right > pWidth) newX = pWidth - __x - i.right;
602
if (newY + __y + i.bottom > pHeight) newY = pHeight - __y - i.bottom;
603
604
getDesktopManager().dragFrame(frame, newX, newY);
605
return;
606
}
607
608
@Override
609
public void mouseMoved(final MouseEvent e) {
610
if (didForwardEvent(e)) return;
611
updateRollover(e);
612
}
613
614
// guards against accidental infinite recursion
615
boolean isTryingToForwardEvent = false;
616
boolean didForwardEvent(final MouseEvent e) {
617
if (isTryingToForwardEvent) return true; // we didn't actually...but we wound up back where we started.
618
619
isTryingToForwardEvent = true;
620
final boolean didForwardEvent = didForwardEventInternal(e);
621
isTryingToForwardEvent = false;
622
623
return didForwardEvent;
624
}
625
@SuppressWarnings("deprecation")
626
boolean didForwardEventInternal(final MouseEvent e) {
627
if (fDraggingFrame) return false;
628
629
final Point originalPoint = e.getPoint();
630
if (!isEventInWindowShadow(originalPoint)) return false;
631
632
final Container parent = frame.getParent();
633
if (!(parent instanceof JDesktopPane)) return false;
634
final JDesktopPane pane = (JDesktopPane)parent;
635
final Point parentPoint = SwingUtilities.convertPoint(frame, originalPoint, parent);
636
637
/* // debug drawing
638
Graphics g = parent.getGraphics();
639
g.setColor(Color.red);
640
g.drawLine(parentPoint.x, parentPoint.y, parentPoint.x, parentPoint.y);
641
*/
642
643
final Component hitComponent = findComponentToHitBehindMe(pane, parentPoint);
644
if (hitComponent == null || hitComponent == frame) return false;
645
646
final Point hitComponentPoint = SwingUtilities.convertPoint(pane, parentPoint, hitComponent);
647
hitComponent.dispatchEvent(
648
new MouseEvent(hitComponent, e.getID(), e.getWhen(),
649
e.getModifiers(), hitComponentPoint.x,
650
hitComponentPoint.y, e.getClickCount(),
651
e.isPopupTrigger(), e.getButton()));
652
return true;
653
}
654
655
Component findComponentToHitBehindMe(final JDesktopPane pane, final Point parentPoint) {
656
final JInternalFrame[] allFrames = pane.getAllFrames();
657
658
boolean foundSelf = false;
659
for (final JInternalFrame f : allFrames) {
660
if (f == frame) { foundSelf = true; continue; }
661
if (!foundSelf) continue;
662
663
final Rectangle bounds = f.getBounds();
664
if (bounds.contains(parentPoint)) return f;
665
}
666
667
return pane;
668
}
669
670
boolean isEventInWindowShadow(final Point point) {
671
final Rectangle bounds = frame.getBounds();
672
final Insets insets = frame.getInsets();
673
insets.top -= fAquaBorder.getTitleHeight();
674
675
if (point.x < insets.left) return true;
676
if (point.x > bounds.width - insets.right) return true;
677
if (point.y < insets.top) return true;
678
if (point.y > bounds.height - insets.bottom) return true;
679
680
return false;
681
}
682
}
683
684
static void updateComponentTreeUIActivation(final Component c, final Object active) {
685
if (c instanceof javax.swing.JComponent) {
686
((javax.swing.JComponent)c).putClientProperty(AquaFocusHandler.FRAME_ACTIVE_PROPERTY, active);
687
}
688
689
Component[] children = null;
690
691
if (c instanceof javax.swing.JMenu) {
692
children = ((javax.swing.JMenu)c).getMenuComponents();
693
} else if (c instanceof Container) {
694
children = ((Container)c).getComponents();
695
}
696
697
if (children != null) {
698
for (final Component element : children) {
699
updateComponentTreeUIActivation(element, active);
700
}
701
}
702
}
703
704
class PropertyListener implements PropertyChangeListener {
705
@Override
706
public void propertyChange(final PropertyChangeEvent e) {
707
final String name = e.getPropertyName();
708
if (FRAME_TYPE.equals(name)) {
709
if (e.getNewValue() instanceof String) {
710
setFrameType((String)e.getNewValue());
711
}
712
} else if (IS_PALETTE_PROPERTY.equals(name)) {
713
if (e.getNewValue() != null) {
714
setPalette(((Boolean)e.getNewValue()).booleanValue());
715
} else {
716
setPalette(false);
717
}
718
// TODO: CPlatformWindow?
719
} else if ("windowModified".equals(name) || CPlatformWindow.WINDOW_DOCUMENT_MODIFIED.equals(name)) {
720
// repaint title bar
721
setDocumentEdited(((Boolean)e.getNewValue()).booleanValue());
722
frame.repaint(0, 0, frame.getWidth(), frame.getBorder().getBorderInsets(frame).top);
723
} else if ("resizable".equals(name) || "state".equals(name) || "iconable".equals(name) || "maximizable".equals(name) || "closable".equals(name)) {
724
if ("resizable".equals(name)) {
725
frame.revalidate();
726
}
727
frame.repaint();
728
} else if ("title".equals(name)) {
729
frame.repaint();
730
} else if ("componentOrientation".equals(name)) {
731
frame.revalidate();
732
frame.repaint();
733
} else if (JInternalFrame.IS_SELECTED_PROPERTY.equals(name)) {
734
final Component source = (Component)(e.getSource());
735
updateComponentTreeUIActivation(source, frame.isSelected() ? Boolean.TRUE : Boolean.FALSE);
736
}
737
738
}
739
} // end class PaletteListener
740
741
private static final InternalFrameShadow documentWindowShadow = new InternalFrameShadow() {
742
@Override
743
Border getForegroundShadowBorder() {
744
return new AquaUtils.SlicedShadowBorder(new Painter() {
745
@Override
746
public void paint(final Graphics g, final int x, final int y, final int w, final int h) {
747
g.setColor(new Color(0, 0, 0, 196));
748
g.fillRoundRect(x, y, w, h, 16, 16);
749
g.fillRect(x, y + h - 16, w, 16);
750
}
751
}, new Painter() {
752
@Override
753
public void paint(final Graphics g, int x, int y, int w, int h) {
754
g.setColor(new Color(0, 0, 0, 64));
755
g.drawLine(x + 2, y - 8, x + w - 2, y - 8);
756
}
757
},
758
0, 7, 1.1f, 1.0f, 24, 51, 51, 25, 25, 25, 25);
759
}
760
761
@Override
762
Border getBackgroundShadowBorder() {
763
return new AquaUtils.SlicedShadowBorder(new Painter() {
764
@Override
765
public void paint(final Graphics g, final int x, final int y, final int w, final int h) {
766
g.setColor(new Color(0, 0, 0, 128));
767
g.fillRoundRect(x - 3, y - 8, w + 6, h, 16, 16);
768
g.fillRect(x - 3, y + h - 20, w + 6, 19);
769
}
770
}, new Painter() {
771
@Override
772
public void paint(final Graphics g, int x, int y, int w, int h) {
773
g.setColor(new Color(0, 0, 0, 32));
774
g.drawLine(x, y - 11, x + w - 1, y - 11);
775
}
776
},
777
0, 0, 3.0f, 1.0f, 10, 51, 51, 25, 25, 25, 25);
778
}
779
};
780
781
private static final InternalFrameShadow paletteWindowShadow = new InternalFrameShadow() {
782
@Override
783
Border getForegroundShadowBorder() {
784
return new AquaUtils.SlicedShadowBorder(new Painter() {
785
@Override
786
public void paint(final Graphics g, final int x, final int y, final int w, final int h) {
787
g.setColor(new Color(0, 0, 0, 128));
788
g.fillRect(x, y + 3, w, h - 3);
789
}
790
}, null,
791
0, 3, 1.0f, 1.0f, 10, 25, 25, 12, 12, 12, 12);
792
}
793
794
@Override
795
Border getBackgroundShadowBorder() {
796
return getForegroundShadowBorder();
797
}
798
};
799
800
@SuppressWarnings("serial") // Superclass is not serializable across versions
801
static class CompoundUIBorder extends CompoundBorder implements UIResource {
802
public CompoundUIBorder(final Border inside, final Border outside) { super(inside, outside); }
803
}
804
805
abstract static class InternalFrameShadow extends RecyclableSingleton<Border> {
806
abstract Border getForegroundShadowBorder();
807
abstract Border getBackgroundShadowBorder();
808
809
@Override
810
protected Border getInstance() {
811
final Border fgShadow = getForegroundShadowBorder();
812
final Border bgShadow = getBackgroundShadowBorder();
813
814
return new Border() {
815
@Override
816
public Insets getBorderInsets(final Component c) {
817
return fgShadow.getBorderInsets(c);
818
}
819
820
@Override
821
public boolean isBorderOpaque() {
822
return false;
823
}
824
825
@Override
826
public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int w, final int h) {
827
if (((JInternalFrame)c).isSelected()) {
828
fgShadow.paintBorder(c, g, x, y, w, h);
829
} else {
830
bgShadow.paintBorder(c, g, x, y, w, h);
831
}
832
}
833
};
834
}
835
}
836
837
private static final RecyclableSingleton<Icon> RESIZE_ICON = new RecyclableSingleton<Icon>() {
838
@Override
839
protected Icon getInstance() {
840
return new AquaIcon.ScalingJRSUIIcon(11, 11) {
841
@Override
842
public void initIconPainter(final AquaPainter<JRSUIState> iconState) {
843
iconState.state.set(Widget.GROW_BOX_TEXTURED);
844
iconState.state.set(WindowType.UTILITY);
845
}
846
};
847
}
848
};
849
850
@SuppressWarnings("serial") // Superclass is not serializable across versions
851
private final class ResizeBox extends JLabel
852
implements MouseListener, MouseMotionListener, MouseWheelListener,
853
ComponentListener, PropertyChangeListener, UIResource {
854
855
private final JLayeredPane layeredPane;
856
private Dimension originalSize;
857
private Point originalLocation;
858
859
ResizeBox(final JLayeredPane layeredPane) {
860
super(RESIZE_ICON.get());
861
setSize(11, 11);
862
this.layeredPane = layeredPane;
863
864
addMouseListener(this);
865
addMouseMotionListener(this);
866
addMouseWheelListener(this);
867
}
868
869
void addListeners() {
870
frame.addPropertyChangeListener("resizable", this);
871
}
872
873
void removeListeners() {
874
frame.removePropertyChangeListener("resizable", this);
875
}
876
877
void repositionResizeBox() {
878
if (frame == null) { setSize(0, 0); } else { setSize(11, 11); }
879
setLocation(layeredPane.getWidth() - 12, layeredPane.getHeight() - 12);
880
}
881
882
void resizeInternalFrame(final Point pt) {
883
if (originalLocation == null || frame == null) return;
884
885
final Container parent = frame.getParent();
886
if (!(parent instanceof JDesktopPane)) return;
887
888
final Point newPoint = SwingUtilities.convertPoint(this, pt, frame);
889
int deltaX = originalLocation.x - newPoint.x;
890
int deltaY = originalLocation.y - newPoint.y;
891
final Dimension min = frame.getMinimumSize();
892
final Dimension max = frame.getMaximumSize();
893
894
final int newX = frame.getX();
895
final int newY = frame.getY();
896
int newW = frame.getWidth();
897
int newH = frame.getHeight();
898
899
final Rectangle parentBounds = parent.getBounds();
900
901
if (originalSize.width - deltaX < min.width) {
902
deltaX = originalSize.width - min.width;
903
} else if (originalSize.width - deltaX > max.width) {
904
deltaX = -(max.width - originalSize.width);
905
}
906
907
if (newX + originalSize.width - deltaX > parentBounds.width) {
908
deltaX = newX + originalSize.width - parentBounds.width;
909
}
910
911
if (originalSize.height - deltaY < min.height) {
912
deltaY = originalSize.height - min.height;
913
} else if (originalSize.height - deltaY > max.height) {
914
deltaY = -(max.height - originalSize.height);
915
}
916
917
if (newY + originalSize.height - deltaY > parentBounds.height) {
918
deltaY = newY + originalSize.height - parentBounds.height;
919
}
920
921
newW = originalSize.width - deltaX;
922
newH = originalSize.height - deltaY;
923
924
getDesktopManager().resizeFrame(frame, newX, newY, newW, newH);
925
}
926
927
boolean testGrowboxPoint(final int x, final int y, final int w, final int h) {
928
return (w - x) + (h - y) < 12;
929
}
930
931
@SuppressWarnings("deprecation")
932
void forwardEventToFrame(final MouseEvent e) {
933
final Point pt = new Point();
934
final Component c = getComponentToForwardTo(e, pt);
935
if (c == null) return;
936
c.dispatchEvent(
937
new MouseEvent(c, e.getID(), e.getWhen(), e.getModifiers(),
938
pt.x, pt.y, e.getClickCount(),
939
e.isPopupTrigger(), e.getButton()));
940
}
941
942
Component getComponentToForwardTo(final MouseEvent e, final Point dst) {
943
if (frame == null) return null;
944
final Container contentPane = frame.getContentPane();
945
if (contentPane == null) return null;
946
Point pt = SwingUtilities.convertPoint(this, e.getPoint(), contentPane);
947
final Component c = SwingUtilities.getDeepestComponentAt(contentPane, pt.x, pt.y);
948
if (c == null) return null;
949
pt = SwingUtilities.convertPoint(contentPane, pt, c);
950
if (dst != null) dst.setLocation(pt);
951
return c;
952
}
953
954
@Override
955
public void mouseClicked(final MouseEvent e) {
956
forwardEventToFrame(e);
957
}
958
959
@Override
960
public void mouseEntered(final MouseEvent e) { }
961
962
@Override
963
public void mouseExited(final MouseEvent e) { }
964
965
@Override
966
public void mousePressed(final MouseEvent e) {
967
if (frame == null) return;
968
969
if (frame.isResizable() && !frame.isMaximum() && testGrowboxPoint(e.getX(), e.getY(), getWidth(), getHeight())) {
970
originalLocation = SwingUtilities.convertPoint(this, e.getPoint(), frame);
971
originalSize = frame.getSize();
972
getDesktopManager().beginResizingFrame(frame, SwingConstants.SOUTH_EAST);
973
return;
974
}
975
976
forwardEventToFrame(e);
977
}
978
979
@Override
980
public void mouseReleased(final MouseEvent e) {
981
if (originalLocation != null) {
982
resizeInternalFrame(e.getPoint());
983
originalLocation = null;
984
getDesktopManager().endResizingFrame(frame);
985
return;
986
}
987
988
forwardEventToFrame(e);
989
}
990
991
@Override
992
public void mouseDragged(final MouseEvent e) {
993
resizeInternalFrame(e.getPoint());
994
repositionResizeBox();
995
}
996
997
@Override
998
public void mouseMoved(final MouseEvent e) { }
999
1000
@Override
1001
@SuppressWarnings("deprecation")
1002
public void mouseWheelMoved(final MouseWheelEvent e) {
1003
final Point pt = new Point();
1004
final Component c = getComponentToForwardTo(e, pt);
1005
if (c == null) return;
1006
c.dispatchEvent(new MouseWheelEvent(c, e.getID(), e.getWhen(),
1007
e.getModifiers(), pt.x, pt.y, e.getXOnScreen(), e.getYOnScreen(),
1008
e.getClickCount(), e.isPopupTrigger(), e.getScrollType(),
1009
e.getScrollAmount(), e.getWheelRotation(),
1010
e.getPreciseWheelRotation()));
1011
}
1012
1013
@Override
1014
public void componentResized(final ComponentEvent e) {
1015
repositionResizeBox();
1016
}
1017
1018
@Override
1019
public void componentShown(final ComponentEvent e) {
1020
repositionResizeBox();
1021
}
1022
1023
@Override
1024
public void componentMoved(final ComponentEvent e) {
1025
repositionResizeBox();
1026
}
1027
1028
@Override
1029
public void componentHidden(final ComponentEvent e) { }
1030
1031
@Override
1032
public void propertyChange(final PropertyChangeEvent evt) {
1033
if (!"resizable".equals(evt.getPropertyName())) return;
1034
setVisible(Boolean.TRUE.equals(evt.getNewValue()));
1035
}
1036
}
1037
}
1038
1039