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/javax/swing/DefaultDesktopManager.java
38829 views
1
/*
2
* Copyright (c) 1997, 2011, 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
27
package javax.swing;
28
29
import com.sun.awt.AWTUtilities;
30
import sun.awt.AWTAccessor;
31
import sun.awt.SunToolkit;
32
33
import java.awt.*;
34
import java.beans.PropertyVetoException;
35
36
/** This is an implementation of the <code>DesktopManager</code>.
37
* It currently implements the basic behaviors for managing
38
* <code>JInternalFrame</code>s in an arbitrary parent.
39
* <code>JInternalFrame</code>s that are not children of a
40
* <code>JDesktop</code> will use this component
41
* to handle their desktop-like actions.
42
* <p>This class provides a policy for the various JInternalFrame methods,
43
* it is not meant to be called directly rather the various JInternalFrame
44
* methods will call into the DesktopManager.</p>
45
* @see JDesktopPane
46
* @see JInternalFrame
47
* @author David Kloba
48
* @author Steve Wilson
49
*/
50
public class DefaultDesktopManager implements DesktopManager, java.io.Serializable {
51
final static String HAS_BEEN_ICONIFIED_PROPERTY = "wasIconOnce";
52
53
final static int DEFAULT_DRAG_MODE = 0;
54
final static int OUTLINE_DRAG_MODE = 1;
55
final static int FASTER_DRAG_MODE = 2;
56
57
int dragMode = DEFAULT_DRAG_MODE;
58
59
private transient Rectangle currentBounds = null;
60
private transient Graphics desktopGraphics = null;
61
private transient Rectangle desktopBounds = null;
62
private transient Rectangle[] floatingItems = {};
63
64
/**
65
* Set to true when the user actually drags a frame vs clicks on it
66
* to start the drag operation. This is only used when dragging with
67
* FASTER_DRAG_MODE.
68
*/
69
private transient boolean didDrag;
70
71
/** Normally this method will not be called. If it is, it
72
* try to determine the appropriate parent from the desktopIcon of the frame.
73
* Will remove the desktopIcon from its parent if it successfully adds the frame.
74
*/
75
public void openFrame(JInternalFrame f) {
76
if(f.getDesktopIcon().getParent() != null) {
77
f.getDesktopIcon().getParent().add(f);
78
removeIconFor(f);
79
}
80
}
81
82
/**
83
* Removes the frame, and, if necessary, the
84
* <code>desktopIcon</code>, from its parent.
85
* @param f the <code>JInternalFrame</code> to be removed
86
*/
87
public void closeFrame(JInternalFrame f) {
88
JDesktopPane d = f.getDesktopPane();
89
if (d == null) {
90
return;
91
}
92
boolean findNext = f.isSelected();
93
Container c = f.getParent();
94
JInternalFrame nextFrame = null;
95
if (findNext) {
96
nextFrame = d.getNextFrame(f);
97
try { f.setSelected(false); } catch (PropertyVetoException e2) { }
98
}
99
if(c != null) {
100
c.remove(f); // Removes the focus.
101
c.repaint(f.getX(), f.getY(), f.getWidth(), f.getHeight());
102
}
103
removeIconFor(f);
104
if(f.getNormalBounds() != null)
105
f.setNormalBounds(null);
106
if(wasIcon(f))
107
setWasIcon(f, null);
108
if (nextFrame != null) {
109
try { nextFrame.setSelected(true); }
110
catch (PropertyVetoException e2) { }
111
} else if (findNext && d.getComponentCount() == 0) {
112
// It was selected and was the last component on the desktop.
113
d.requestFocus();
114
}
115
}
116
117
/**
118
* Resizes the frame to fill its parents bounds.
119
* @param f the frame to be resized
120
*/
121
public void maximizeFrame(JInternalFrame f) {
122
if (f.isIcon()) {
123
try {
124
// In turn calls deiconifyFrame in the desktop manager.
125
// That method will handle the maximization of the frame.
126
f.setIcon(false);
127
} catch (PropertyVetoException e2) {
128
}
129
} else {
130
f.setNormalBounds(f.getBounds());
131
Rectangle desktopBounds = f.getParent().getBounds();
132
setBoundsForFrame(f, 0, 0,
133
desktopBounds.width, desktopBounds.height);
134
}
135
136
// Set the maximized frame as selected.
137
try {
138
f.setSelected(true);
139
} catch (PropertyVetoException e2) {
140
}
141
}
142
143
/**
144
* Restores the frame back to its size and position prior
145
* to a <code>maximizeFrame</code> call.
146
* @param f the <code>JInternalFrame</code> to be restored
147
*/
148
public void minimizeFrame(JInternalFrame f) {
149
// If the frame was an icon restore it back to an icon.
150
if (f.isIcon()) {
151
iconifyFrame(f);
152
return;
153
}
154
155
if ((f.getNormalBounds()) != null) {
156
Rectangle r = f.getNormalBounds();
157
f.setNormalBounds(null);
158
try { f.setSelected(true); } catch (PropertyVetoException e2) { }
159
setBoundsForFrame(f, r.x, r.y, r.width, r.height);
160
}
161
}
162
163
/**
164
* Removes the frame from its parent and adds its
165
* <code>desktopIcon</code> to the parent.
166
* @param f the <code>JInternalFrame</code> to be iconified
167
*/
168
public void iconifyFrame(JInternalFrame f) {
169
JInternalFrame.JDesktopIcon desktopIcon;
170
Container c = f.getParent();
171
JDesktopPane d = f.getDesktopPane();
172
boolean findNext = f.isSelected();
173
desktopIcon = f.getDesktopIcon();
174
if(!wasIcon(f)) {
175
Rectangle r = getBoundsForIconOf(f);
176
desktopIcon.setBounds(r.x, r.y, r.width, r.height);
177
// we must validate the hierarchy to not break the hw/lw mixing
178
desktopIcon.revalidate();
179
setWasIcon(f, Boolean.TRUE);
180
}
181
182
if (c == null || d == null) {
183
return;
184
}
185
186
if (c instanceof JLayeredPane) {
187
JLayeredPane lp = (JLayeredPane)c;
188
int layer = lp.getLayer(f);
189
lp.putLayer(desktopIcon, layer);
190
}
191
192
// If we are maximized we already have the normal bounds recorded
193
// don't try to re-record them, otherwise we incorrectly set the
194
// normal bounds to maximized state.
195
if (!f.isMaximum()) {
196
f.setNormalBounds(f.getBounds());
197
}
198
d.setComponentOrderCheckingEnabled(false);
199
c.remove(f);
200
c.add(desktopIcon);
201
d.setComponentOrderCheckingEnabled(true);
202
c.repaint(f.getX(), f.getY(), f.getWidth(), f.getHeight());
203
if (findNext) {
204
if (d.selectFrame(true) == null) {
205
// The icon is the last frame.
206
f.restoreSubcomponentFocus();
207
}
208
}
209
}
210
211
/**
212
* Removes the desktopIcon from its parent and adds its frame
213
* to the parent.
214
* @param f the <code>JInternalFrame</code> to be de-iconified
215
*/
216
public void deiconifyFrame(JInternalFrame f) {
217
JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon();
218
Container c = desktopIcon.getParent();
219
JDesktopPane d = f.getDesktopPane();
220
if (c != null && d != null) {
221
c.add(f);
222
// If the frame is to be restored to a maximized state make
223
// sure it still fills the whole desktop.
224
if (f.isMaximum()) {
225
Rectangle desktopBounds = c.getBounds();
226
if (f.getWidth() != desktopBounds.width ||
227
f.getHeight() != desktopBounds.height) {
228
setBoundsForFrame(f, 0, 0,
229
desktopBounds.width, desktopBounds.height);
230
}
231
}
232
removeIconFor(f);
233
if (f.isSelected()) {
234
f.moveToFront();
235
f.restoreSubcomponentFocus();
236
}
237
else {
238
try {
239
f.setSelected(true);
240
} catch (PropertyVetoException e2) {}
241
242
}
243
}
244
}
245
246
/** This will activate <b>f</b> moving it to the front. It will
247
* set the current active frame's (if any)
248
* <code>IS_SELECTED_PROPERTY</code> to <code>false</code>.
249
* There can be only one active frame across all Layers.
250
* @param f the <code>JInternalFrame</code> to be activated
251
*/
252
public void activateFrame(JInternalFrame f) {
253
Container p = f.getParent();
254
Component[] c;
255
JDesktopPane d = f.getDesktopPane();
256
JInternalFrame currentlyActiveFrame =
257
(d == null) ? null : d.getSelectedFrame();
258
// fix for bug: 4162443
259
if(p == null) {
260
// If the frame is not in parent, its icon maybe, check it
261
p = f.getDesktopIcon().getParent();
262
if(p == null)
263
return;
264
}
265
// we only need to keep track of the currentActive InternalFrame, if any
266
if (currentlyActiveFrame == null){
267
if (d != null) { d.setSelectedFrame(f);}
268
} else if (currentlyActiveFrame != f) {
269
// if not the same frame as the current active
270
// we deactivate the current
271
if (currentlyActiveFrame.isSelected()) {
272
try {
273
currentlyActiveFrame.setSelected(false);
274
}
275
catch(PropertyVetoException e2) {}
276
}
277
if (d != null) { d.setSelectedFrame(f);}
278
}
279
f.moveToFront();
280
}
281
282
// implements javax.swing.DesktopManager
283
public void deactivateFrame(JInternalFrame f) {
284
JDesktopPane d = f.getDesktopPane();
285
JInternalFrame currentlyActiveFrame =
286
(d == null) ? null : d.getSelectedFrame();
287
if (currentlyActiveFrame == f)
288
d.setSelectedFrame(null);
289
}
290
291
// implements javax.swing.DesktopManager
292
public void beginDraggingFrame(JComponent f) {
293
setupDragMode(f);
294
295
if (dragMode == FASTER_DRAG_MODE) {
296
Component desktop = f.getParent();
297
floatingItems = findFloatingItems(f);
298
currentBounds = f.getBounds();
299
if (desktop instanceof JComponent) {
300
desktopBounds = ((JComponent)desktop).getVisibleRect();
301
}
302
else {
303
desktopBounds = desktop.getBounds();
304
desktopBounds.x = desktopBounds.y = 0;
305
}
306
desktopGraphics = JComponent.safelyGetGraphics(desktop);
307
((JInternalFrame)f).isDragging = true;
308
didDrag = false;
309
}
310
311
}
312
313
private void setupDragMode(JComponent f) {
314
JDesktopPane p = getDesktopPane(f);
315
Container parent = f.getParent();
316
dragMode = DEFAULT_DRAG_MODE;
317
if (p != null) {
318
String mode = (String)p.getClientProperty("JDesktopPane.dragMode");
319
Window window = SwingUtilities.getWindowAncestor(f);
320
if (window != null && !AWTUtilities.isWindowOpaque(window)) {
321
dragMode = DEFAULT_DRAG_MODE;
322
} else if (mode != null && mode.equals("outline")) {
323
dragMode = OUTLINE_DRAG_MODE;
324
} else if (mode != null && mode.equals("faster")
325
&& f instanceof JInternalFrame
326
&& ((JInternalFrame)f).isOpaque() &&
327
(parent == null || parent.isOpaque())) {
328
dragMode = FASTER_DRAG_MODE;
329
} else {
330
if (p.getDragMode() == JDesktopPane.OUTLINE_DRAG_MODE ) {
331
dragMode = OUTLINE_DRAG_MODE;
332
} else if ( p.getDragMode() == JDesktopPane.LIVE_DRAG_MODE
333
&& f instanceof JInternalFrame
334
&& ((JInternalFrame)f).isOpaque()) {
335
dragMode = FASTER_DRAG_MODE;
336
} else {
337
dragMode = DEFAULT_DRAG_MODE;
338
}
339
}
340
}
341
}
342
343
private transient Point currentLoc = null;
344
345
/**
346
* Moves the visible location of the frame being dragged
347
* to the location specified. The means by which this occurs can vary depending
348
* on the dragging algorithm being used. The actual logical location of the frame
349
* might not change until <code>endDraggingFrame</code> is called.
350
*/
351
public void dragFrame(JComponent f, int newX, int newY) {
352
353
if (dragMode == OUTLINE_DRAG_MODE) {
354
JDesktopPane desktopPane = getDesktopPane(f);
355
if (desktopPane != null){
356
Graphics g = JComponent.safelyGetGraphics(desktopPane);
357
358
g.setXORMode(Color.white);
359
if (currentLoc != null) {
360
g.drawRect(currentLoc.x, currentLoc.y,
361
f.getWidth()-1, f.getHeight()-1);
362
}
363
g.drawRect( newX, newY, f.getWidth()-1, f.getHeight()-1);
364
/* Work around for 6635462: XOR mode may cause a SurfaceLost on first use.
365
* Swing doesn't expect that its XOR drawRect did
366
* not complete, so believes that on re-entering at
367
* the next update location, that there is an XOR rect
368
* to draw out at "currentLoc". But in fact
369
* its now got a new clean surface without that rect,
370
* so drawing it "out" in fact draws it on, leaving garbage.
371
* So only update/set currentLoc if the draw completed.
372
*/
373
sun.java2d.SurfaceData sData =
374
((sun.java2d.SunGraphics2D)g).getSurfaceData();
375
376
if (!sData.isSurfaceLost()) {
377
currentLoc = new Point (newX, newY);
378
}
379
;
380
g.dispose();
381
}
382
} else if (dragMode == FASTER_DRAG_MODE) {
383
dragFrameFaster(f, newX, newY);
384
} else {
385
setBoundsForFrame(f, newX, newY, f.getWidth(), f.getHeight());
386
}
387
}
388
389
// implements javax.swing.DesktopManager
390
public void endDraggingFrame(JComponent f) {
391
if ( dragMode == OUTLINE_DRAG_MODE && currentLoc != null) {
392
setBoundsForFrame(f, currentLoc.x, currentLoc.y, f.getWidth(), f.getHeight() );
393
currentLoc = null;
394
} else if (dragMode == FASTER_DRAG_MODE) {
395
currentBounds = null;
396
if (desktopGraphics != null) {
397
desktopGraphics.dispose();
398
desktopGraphics = null;
399
}
400
desktopBounds = null;
401
((JInternalFrame)f).isDragging = false;
402
}
403
}
404
405
// implements javax.swing.DesktopManager
406
public void beginResizingFrame(JComponent f, int direction) {
407
setupDragMode(f);
408
}
409
410
/**
411
* Calls <code>setBoundsForFrame</code> with the new values.
412
* @param f the component to be resized
413
* @param newX the new x-coordinate
414
* @param newY the new y-coordinate
415
* @param newWidth the new width
416
* @param newHeight the new height
417
*/
418
public void resizeFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {
419
420
if ( dragMode == DEFAULT_DRAG_MODE || dragMode == FASTER_DRAG_MODE ) {
421
setBoundsForFrame(f, newX, newY, newWidth, newHeight);
422
} else {
423
JDesktopPane desktopPane = getDesktopPane(f);
424
if (desktopPane != null){
425
Graphics g = JComponent.safelyGetGraphics(desktopPane);
426
427
g.setXORMode(Color.white);
428
if (currentBounds != null) {
429
g.drawRect( currentBounds.x, currentBounds.y, currentBounds.width-1, currentBounds.height-1);
430
}
431
g.drawRect( newX, newY, newWidth-1, newHeight-1);
432
433
// Work around for 6635462, see comment in dragFrame()
434
sun.java2d.SurfaceData sData =
435
((sun.java2d.SunGraphics2D)g).getSurfaceData();
436
if (!sData.isSurfaceLost()) {
437
currentBounds = new Rectangle (newX, newY, newWidth, newHeight);
438
}
439
440
g.setPaintMode();
441
g.dispose();
442
}
443
}
444
445
}
446
447
// implements javax.swing.DesktopManager
448
public void endResizingFrame(JComponent f) {
449
if ( dragMode == OUTLINE_DRAG_MODE && currentBounds != null) {
450
setBoundsForFrame(f, currentBounds.x, currentBounds.y, currentBounds.width, currentBounds.height );
451
currentBounds = null;
452
}
453
}
454
455
456
/** This moves the <code>JComponent</code> and repaints the damaged areas. */
457
public void setBoundsForFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {
458
f.setBounds(newX, newY, newWidth, newHeight);
459
// we must validate the hierarchy to not break the hw/lw mixing
460
f.revalidate();
461
}
462
463
/** Convenience method to remove the desktopIcon of <b>f</b> is necessary. */
464
protected void removeIconFor(JInternalFrame f) {
465
JInternalFrame.JDesktopIcon di = f.getDesktopIcon();
466
Container c = di.getParent();
467
if(c != null) {
468
c.remove(di);
469
c.repaint(di.getX(), di.getY(), di.getWidth(), di.getHeight());
470
}
471
}
472
473
/** The iconifyFrame() code calls this to determine the proper bounds
474
* for the desktopIcon.
475
*/
476
477
protected Rectangle getBoundsForIconOf(JInternalFrame f) {
478
//
479
// Get the icon for this internal frame and its preferred size
480
//
481
482
JInternalFrame.JDesktopIcon icon = f.getDesktopIcon();
483
Dimension prefSize = icon.getPreferredSize();
484
//
485
// Get the parent bounds and child components.
486
//
487
488
Container c = f.getParent();
489
if (c == null) {
490
c = f.getDesktopIcon().getParent();
491
}
492
493
if (c == null) {
494
/* the frame has not yet been added to the parent; how about (0,0) ?*/
495
return new Rectangle(0, 0, prefSize.width, prefSize.height);
496
}
497
498
Rectangle parentBounds = c.getBounds();
499
Component [] components = c.getComponents();
500
501
502
//
503
// Iterate through valid default icon locations and return the
504
// first one that does not intersect any other icons.
505
//
506
507
Rectangle availableRectangle = null;
508
JInternalFrame.JDesktopIcon currentIcon = null;
509
510
int x = 0;
511
int y = parentBounds.height - prefSize.height;
512
int w = prefSize.width;
513
int h = prefSize.height;
514
515
boolean found = false;
516
517
while (!found) {
518
519
availableRectangle = new Rectangle(x,y,w,h);
520
521
found = true;
522
523
for ( int i=0; i<components.length; i++ ) {
524
525
//
526
// Get the icon for this component
527
//
528
529
if ( components[i] instanceof JInternalFrame ) {
530
currentIcon = ((JInternalFrame)components[i]).getDesktopIcon();
531
}
532
else if ( components[i] instanceof JInternalFrame.JDesktopIcon ){
533
currentIcon = (JInternalFrame.JDesktopIcon)components[i];
534
} else
535
/* found a child that's neither an internal frame nor
536
an icon. I don't believe this should happen, but at
537
present it does and causes a null pointer exception.
538
Even when that gets fixed, this code protects against
539
the npe. hania */
540
continue;
541
542
//
543
// If this icon intersects the current location, get next location.
544
//
545
546
if ( !currentIcon.equals(icon) ) {
547
if ( availableRectangle.intersects(currentIcon.getBounds()) ) {
548
found = false;
549
break;
550
}
551
}
552
}
553
554
if (currentIcon == null)
555
/* didn't find any useful children above. This probably shouldn't
556
happen, but this check protects against an npe if it ever does
557
(and it's happening now) */
558
return availableRectangle;
559
560
x += currentIcon.getBounds().width;
561
562
if ( x + w > parentBounds.width ) {
563
x = 0;
564
y -= h;
565
}
566
}
567
568
return(availableRectangle);
569
}
570
571
/**
572
* Stores the bounds of the component just before a maximize call.
573
* @param f the component about to be resized
574
* @param r the normal bounds to be saved away
575
*/
576
protected void setPreviousBounds(JInternalFrame f, Rectangle r) {
577
f.setNormalBounds(r);
578
}
579
580
/**
581
* Gets the normal bounds of the component prior to the component
582
* being maximized.
583
* @param f the <code>JInternalFrame</code> of interest
584
* @return the normal bounds of the component
585
*/
586
protected Rectangle getPreviousBounds(JInternalFrame f) {
587
return f.getNormalBounds();
588
}
589
590
/**
591
* Sets that the component has been iconized and the bounds of the
592
* <code>desktopIcon</code> are valid.
593
*/
594
protected void setWasIcon(JInternalFrame f, Boolean value) {
595
if (value != null) {
596
f.putClientProperty(HAS_BEEN_ICONIFIED_PROPERTY, value);
597
}
598
}
599
600
/**
601
* Returns <code>true</code> if the component has been iconized
602
* and the bounds of the <code>desktopIcon</code> are valid,
603
* otherwise returns <code>false</code>.
604
*
605
* @param f the <code>JInternalFrame</code> of interest
606
* @return <code>true</code> if the component has been iconized;
607
* otherwise returns <code>false</code>
608
*/
609
protected boolean wasIcon(JInternalFrame f) {
610
return (f.getClientProperty(HAS_BEEN_ICONIFIED_PROPERTY) == Boolean.TRUE);
611
}
612
613
614
JDesktopPane getDesktopPane( JComponent frame ) {
615
JDesktopPane pane = null;
616
Component c = frame.getParent();
617
618
// Find the JDesktopPane
619
while ( pane == null ) {
620
if ( c instanceof JDesktopPane ) {
621
pane = (JDesktopPane)c;
622
}
623
else if ( c == null ) {
624
break;
625
}
626
else {
627
c = c.getParent();
628
}
629
}
630
631
return pane;
632
}
633
634
635
// =========== stuff for faster frame dragging ===================
636
637
private void dragFrameFaster(JComponent f, int newX, int newY) {
638
639
Rectangle previousBounds = new Rectangle(currentBounds.x,
640
currentBounds.y,
641
currentBounds.width,
642
currentBounds.height);
643
644
// move the frame
645
currentBounds.x = newX;
646
currentBounds.y = newY;
647
648
if (didDrag) {
649
// Only initiate cleanup if we have actually done a drag.
650
emergencyCleanup(f);
651
}
652
else {
653
didDrag = true;
654
// We reset the danger field as until now we haven't actually
655
// moved the internal frame so we don't need to initiate repaint.
656
((JInternalFrame)f).danger = false;
657
}
658
659
boolean floaterCollision = isFloaterCollision(previousBounds, currentBounds);
660
661
JComponent parent = (JComponent)f.getParent();
662
Rectangle visBounds = previousBounds.intersection(desktopBounds);
663
664
RepaintManager currentManager = RepaintManager.currentManager(f);
665
666
currentManager.beginPaint();
667
try {
668
if(!floaterCollision) {
669
currentManager.copyArea(parent, desktopGraphics, visBounds.x,
670
visBounds.y,
671
visBounds.width,
672
visBounds.height,
673
newX - previousBounds.x,
674
newY - previousBounds.y,
675
true);
676
}
677
678
f.setBounds(currentBounds);
679
680
if (!floaterCollision) {
681
Rectangle r = currentBounds;
682
currentManager.notifyRepaintPerformed(parent, r.x, r.y, r.width, r.height);
683
}
684
685
if(floaterCollision) {
686
// since we couldn't blit we just redraw as fast as possible
687
// the isDragging mucking is to avoid activating emergency
688
// cleanup
689
((JInternalFrame)f).isDragging = false;
690
parent.paintImmediately(currentBounds);
691
((JInternalFrame)f).isDragging = true;
692
}
693
694
// fake out the repaint manager. We'll take care of everything
695
696
currentManager.markCompletelyClean(parent);
697
currentManager.markCompletelyClean(f);
698
699
// compute the minimal newly exposed area
700
// if the rects intersect then we use computeDifference. Otherwise
701
// we'll repaint the entire previous bounds
702
Rectangle[] dirtyRects = null;
703
if ( previousBounds.intersects(currentBounds) ) {
704
dirtyRects = SwingUtilities.computeDifference(previousBounds,
705
currentBounds);
706
} else {
707
dirtyRects = new Rectangle[1];
708
dirtyRects[0] = previousBounds;
709
};
710
711
// Fix the damage
712
for (int i = 0; i < dirtyRects.length; i++) {
713
parent.paintImmediately(dirtyRects[i]);
714
Rectangle r = dirtyRects[i];
715
currentManager.notifyRepaintPerformed(parent, r.x, r.y, r.width, r.height);
716
}
717
718
// new areas of blit were exposed
719
if ( !(visBounds.equals(previousBounds)) ) {
720
dirtyRects = SwingUtilities.computeDifference(previousBounds,
721
desktopBounds);
722
for (int i = 0; i < dirtyRects.length; i++) {
723
dirtyRects[i].x += newX - previousBounds.x;
724
dirtyRects[i].y += newY - previousBounds.y;
725
((JInternalFrame)f).isDragging = false;
726
parent.paintImmediately(dirtyRects[i]);
727
((JInternalFrame)f).isDragging = true;
728
Rectangle r = dirtyRects[i];
729
currentManager.notifyRepaintPerformed(parent, r.x, r.y, r.width, r.height);
730
}
731
732
}
733
} finally {
734
currentManager.endPaint();
735
}
736
737
// update window if it's non-opaque
738
Window topLevel = SwingUtilities.getWindowAncestor(f);
739
Toolkit tk = Toolkit.getDefaultToolkit();
740
if (!topLevel.isOpaque() &&
741
(tk instanceof SunToolkit) &&
742
((SunToolkit)tk).needUpdateWindow())
743
{
744
AWTAccessor.getWindowAccessor().updateWindow(topLevel);
745
}
746
}
747
748
private boolean isFloaterCollision(Rectangle moveFrom, Rectangle moveTo) {
749
if (floatingItems.length == 0) {
750
// System.out.println("no floaters");
751
return false;
752
}
753
754
for (int i = 0; i < floatingItems.length; i++) {
755
boolean intersectsFrom = moveFrom.intersects(floatingItems[i]);
756
if (intersectsFrom) {
757
return true;
758
}
759
boolean intersectsTo = moveTo.intersects(floatingItems[i]);
760
if (intersectsTo) {
761
return true;
762
}
763
}
764
765
return false;
766
}
767
768
private Rectangle[] findFloatingItems(JComponent f) {
769
Container desktop = f.getParent();
770
Component[] children = desktop.getComponents();
771
int i = 0;
772
for (i = 0; i < children.length; i++) {
773
if (children[i] == f) {
774
break;
775
}
776
}
777
// System.out.println(i);
778
Rectangle[] floaters = new Rectangle[i];
779
for (i = 0; i < floaters.length; i++) {
780
floaters[i] = children[i].getBounds();
781
}
782
783
return floaters;
784
}
785
786
/**
787
* This method is here to clean up problems associated
788
* with a race condition which can occur when the full contents
789
* of a copyArea's source argument is not available onscreen.
790
* This uses brute force to clean up in case of possible damage
791
*/
792
private void emergencyCleanup(final JComponent f) {
793
794
if ( ((JInternalFrame)f).danger ) {
795
796
SwingUtilities.invokeLater( new Runnable(){
797
public void run(){
798
799
((JInternalFrame)f).isDragging = false;
800
f.paintImmediately(0,0,
801
f.getWidth(),
802
f.getHeight());
803
804
//finalFrame.repaint();
805
((JInternalFrame)f).isDragging = true;
806
// System.out.println("repair complete");
807
}});
808
809
((JInternalFrame)f).danger = false;
810
}
811
812
}
813
814
815
}
816
817