/*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package javax.swing;
import com.sun.awt.
AWTUtilities;
import sun.awt.
AWTAccessor;
import sun.awt.
SunToolkit;
import java.awt.*;
import java.beans.
PropertyVetoException;
/** This is an implementation of the <code>DesktopManager</code>.
* It currently implements the basic behaviors for managing
* <code>JInternalFrame</code>s in an arbitrary parent.
* <code>JInternalFrame</code>s that are not children of a
* <code>JDesktop</code> will use this component
* to handle their desktop-like actions.
* <p>This class provides a policy for the various JInternalFrame methods,
* it is not meant to be called directly rather the various JInternalFrame
* methods will call into the DesktopManager.</p>
* @see JDesktopPane
* @see JInternalFrame
* @author David Kloba
* @author Steve Wilson
*/
public class
DefaultDesktopManager implements
DesktopManager, java.io.
Serializable {
final static
String HAS_BEEN_ICONIFIED_PROPERTY = "wasIconOnce";
final static int
DEFAULT_DRAG_MODE = 0;
final static int
OUTLINE_DRAG_MODE = 1;
final static int
FASTER_DRAG_MODE = 2;
int
dragMode =
DEFAULT_DRAG_MODE;
private transient
Rectangle currentBounds = null;
private transient
Graphics desktopGraphics = null;
private transient
Rectangle desktopBounds = null;
private transient
Rectangle[]
floatingItems = {};
/**
* Set to true when the user actually drags a frame vs clicks on it
* to start the drag operation. This is only used when dragging with
* FASTER_DRAG_MODE.
*/
private transient boolean
didDrag;
/** Normally this method will not be called. If it is, it
* try to determine the appropriate parent from the desktopIcon of the frame.
* Will remove the desktopIcon from its parent if it successfully adds the frame.
*/
public void
openFrame(
JInternalFrame f) {
if(
f.
getDesktopIcon().
getParent() != null) {
f.
getDesktopIcon().
getParent().
add(
f);
removeIconFor(
f);
}
}
/**
* Removes the frame, and, if necessary, the
* <code>desktopIcon</code>, from its parent.
* @param f the <code>JInternalFrame</code> to be removed
*/
public void
closeFrame(
JInternalFrame f) {
JDesktopPane d =
f.
getDesktopPane();
if (
d == null) {
return;
}
boolean
findNext =
f.
isSelected();
Container c =
f.
getParent();
JInternalFrame nextFrame = null;
if (
findNext) {
nextFrame =
d.
getNextFrame(
f);
try {
f.
setSelected(false); } catch (
PropertyVetoException e2) { }
}
if(
c != null) {
c.
remove(
f); // Removes the focus.
c.
repaint(
f.
getX(),
f.
getY(),
f.
getWidth(),
f.
getHeight());
}
removeIconFor(
f);
if(
f.
getNormalBounds() != null)
f.
setNormalBounds(null);
if(
wasIcon(
f))
setWasIcon(
f, null);
if (
nextFrame != null) {
try {
nextFrame.
setSelected(true); }
catch (
PropertyVetoException e2) { }
} else if (
findNext &&
d.
getComponentCount() == 0) {
// It was selected and was the last component on the desktop.
d.
requestFocus();
}
}
/**
* Resizes the frame to fill its parents bounds.
* @param f the frame to be resized
*/
public void
maximizeFrame(
JInternalFrame f) {
if (
f.
isIcon()) {
try {
// In turn calls deiconifyFrame in the desktop manager.
// That method will handle the maximization of the frame.
f.
setIcon(false);
} catch (
PropertyVetoException e2) {
}
} else {
f.
setNormalBounds(
f.
getBounds());
Rectangle desktopBounds =
f.
getParent().
getBounds();
setBoundsForFrame(
f, 0, 0,
desktopBounds.
width,
desktopBounds.
height);
}
// Set the maximized frame as selected.
try {
f.
setSelected(true);
} catch (
PropertyVetoException e2) {
}
}
/**
* Restores the frame back to its size and position prior
* to a <code>maximizeFrame</code> call.
* @param f the <code>JInternalFrame</code> to be restored
*/
public void
minimizeFrame(
JInternalFrame f) {
// If the frame was an icon restore it back to an icon.
if (
f.
isIcon()) {
iconifyFrame(
f);
return;
}
if ((
f.
getNormalBounds()) != null) {
Rectangle r =
f.
getNormalBounds();
f.
setNormalBounds(null);
try {
f.
setSelected(true); } catch (
PropertyVetoException e2) { }
setBoundsForFrame(
f,
r.
x,
r.
y,
r.
width,
r.
height);
}
}
/**
* Removes the frame from its parent and adds its
* <code>desktopIcon</code> to the parent.
* @param f the <code>JInternalFrame</code> to be iconified
*/
public void
iconifyFrame(
JInternalFrame f) {
JInternalFrame.
JDesktopIcon desktopIcon;
Container c =
f.
getParent();
JDesktopPane d =
f.
getDesktopPane();
boolean
findNext =
f.
isSelected();
desktopIcon =
f.
getDesktopIcon();
if(!
wasIcon(
f)) {
Rectangle r =
getBoundsForIconOf(
f);
desktopIcon.
setBounds(
r.
x,
r.
y,
r.
width,
r.
height);
// we must validate the hierarchy to not break the hw/lw mixing
desktopIcon.
revalidate();
setWasIcon(
f,
Boolean.
TRUE);
}
if (
c == null ||
d == null) {
return;
}
if (
c instanceof
JLayeredPane) {
JLayeredPane lp = (
JLayeredPane)
c;
int
layer =
lp.
getLayer(
f);
lp.
putLayer(
desktopIcon,
layer);
}
// If we are maximized we already have the normal bounds recorded
// don't try to re-record them, otherwise we incorrectly set the
// normal bounds to maximized state.
if (!
f.
isMaximum()) {
f.
setNormalBounds(
f.
getBounds());
}
d.
setComponentOrderCheckingEnabled(false);
c.
remove(
f);
c.
add(
desktopIcon);
d.
setComponentOrderCheckingEnabled(true);
c.
repaint(
f.
getX(),
f.
getY(),
f.
getWidth(),
f.
getHeight());
if (
findNext) {
if (
d.
selectFrame(true) == null) {
// The icon is the last frame.
f.
restoreSubcomponentFocus();
}
}
}
/**
* Removes the desktopIcon from its parent and adds its frame
* to the parent.
* @param f the <code>JInternalFrame</code> to be de-iconified
*/
public void
deiconifyFrame(
JInternalFrame f) {
JInternalFrame.
JDesktopIcon desktopIcon =
f.
getDesktopIcon();
Container c =
desktopIcon.
getParent();
JDesktopPane d =
f.
getDesktopPane();
if (
c != null &&
d != null) {
c.
add(
f);
// If the frame is to be restored to a maximized state make
// sure it still fills the whole desktop.
if (
f.
isMaximum()) {
Rectangle desktopBounds =
c.
getBounds();
if (
f.
getWidth() !=
desktopBounds.
width ||
f.
getHeight() !=
desktopBounds.
height) {
setBoundsForFrame(
f, 0, 0,
desktopBounds.
width,
desktopBounds.
height);
}
}
removeIconFor(
f);
if (
f.
isSelected()) {
f.
moveToFront();
f.
restoreSubcomponentFocus();
}
else {
try {
f.
setSelected(true);
} catch (
PropertyVetoException e2) {}
}
}
}
/** This will activate <b>f</b> moving it to the front. It will
* set the current active frame's (if any)
* <code>IS_SELECTED_PROPERTY</code> to <code>false</code>.
* There can be only one active frame across all Layers.
* @param f the <code>JInternalFrame</code> to be activated
*/
public void
activateFrame(
JInternalFrame f) {
Container p =
f.
getParent();
Component[]
c;
JDesktopPane d =
f.
getDesktopPane();
JInternalFrame currentlyActiveFrame =
(
d == null) ? null :
d.
getSelectedFrame();
// fix for bug: 4162443
if(
p == null) {
// If the frame is not in parent, its icon maybe, check it
p =
f.
getDesktopIcon().
getParent();
if(
p == null)
return;
}
// we only need to keep track of the currentActive InternalFrame, if any
if (
currentlyActiveFrame == null){
if (
d != null) {
d.
setSelectedFrame(
f);}
} else if (
currentlyActiveFrame !=
f) {
// if not the same frame as the current active
// we deactivate the current
if (
currentlyActiveFrame.
isSelected()) {
try {
currentlyActiveFrame.
setSelected(false);
}
catch(
PropertyVetoException e2) {}
}
if (
d != null) {
d.
setSelectedFrame(
f);}
}
f.
moveToFront();
}
// implements javax.swing.DesktopManager
public void
deactivateFrame(
JInternalFrame f) {
JDesktopPane d =
f.
getDesktopPane();
JInternalFrame currentlyActiveFrame =
(
d == null) ? null :
d.
getSelectedFrame();
if (
currentlyActiveFrame ==
f)
d.
setSelectedFrame(null);
}
// implements javax.swing.DesktopManager
public void
beginDraggingFrame(
JComponent f) {
setupDragMode(
f);
if (
dragMode ==
FASTER_DRAG_MODE) {
Component desktop =
f.
getParent();
floatingItems =
findFloatingItems(
f);
currentBounds =
f.
getBounds();
if (
desktop instanceof
JComponent) {
desktopBounds = ((
JComponent)
desktop).
getVisibleRect();
}
else {
desktopBounds =
desktop.
getBounds();
desktopBounds.
x =
desktopBounds.
y = 0;
}
desktopGraphics =
JComponent.
safelyGetGraphics(
desktop);
((
JInternalFrame)
f).
isDragging = true;
didDrag = false;
}
}
private void
setupDragMode(
JComponent f) {
JDesktopPane p =
getDesktopPane(
f);
Container parent =
f.
getParent();
dragMode =
DEFAULT_DRAG_MODE;
if (
p != null) {
String mode = (
String)
p.
getClientProperty("JDesktopPane.dragMode");
Window window =
SwingUtilities.
getWindowAncestor(
f);
if (
window != null && !
AWTUtilities.
isWindowOpaque(
window)) {
dragMode =
DEFAULT_DRAG_MODE;
} else if (
mode != null &&
mode.
equals("outline")) {
dragMode =
OUTLINE_DRAG_MODE;
} else if (
mode != null &&
mode.
equals("faster")
&&
f instanceof
JInternalFrame
&& ((
JInternalFrame)
f).
isOpaque() &&
(
parent == null ||
parent.
isOpaque())) {
dragMode =
FASTER_DRAG_MODE;
} else {
if (
p.
getDragMode() ==
JDesktopPane.
OUTLINE_DRAG_MODE ) {
dragMode =
OUTLINE_DRAG_MODE;
} else if (
p.
getDragMode() ==
JDesktopPane.
LIVE_DRAG_MODE
&&
f instanceof
JInternalFrame
&& ((
JInternalFrame)
f).
isOpaque()) {
dragMode =
FASTER_DRAG_MODE;
} else {
dragMode =
DEFAULT_DRAG_MODE;
}
}
}
}
private transient
Point currentLoc = null;
/**
* Moves the visible location of the frame being dragged
* to the location specified. The means by which this occurs can vary depending
* on the dragging algorithm being used. The actual logical location of the frame
* might not change until <code>endDraggingFrame</code> is called.
*/
public void
dragFrame(
JComponent f, int
newX, int
newY) {
if (
dragMode ==
OUTLINE_DRAG_MODE) {
JDesktopPane desktopPane =
getDesktopPane(
f);
if (
desktopPane != null){
Graphics g =
JComponent.
safelyGetGraphics(
desktopPane);
g.
setXORMode(
Color.
white);
if (
currentLoc != null) {
g.
drawRect(
currentLoc.
x,
currentLoc.
y,
f.
getWidth()-1,
f.
getHeight()-1);
}
g.
drawRect(
newX,
newY,
f.
getWidth()-1,
f.
getHeight()-1);
/* Work around for 6635462: XOR mode may cause a SurfaceLost on first use.
* Swing doesn't expect that its XOR drawRect did
* not complete, so believes that on re-entering at
* the next update location, that there is an XOR rect
* to draw out at "currentLoc". But in fact
* its now got a new clean surface without that rect,
* so drawing it "out" in fact draws it on, leaving garbage.
* So only update/set currentLoc if the draw completed.
*/
sun.java2d.
SurfaceData sData =
((sun.java2d.
SunGraphics2D)
g).
getSurfaceData();
if (!
sData.
isSurfaceLost()) {
currentLoc = new
Point (
newX,
newY);
}
;
g.
dispose();
}
} else if (
dragMode ==
FASTER_DRAG_MODE) {
dragFrameFaster(
f,
newX,
newY);
} else {
setBoundsForFrame(
f,
newX,
newY,
f.
getWidth(),
f.
getHeight());
}
}
// implements javax.swing.DesktopManager
public void
endDraggingFrame(
JComponent f) {
if (
dragMode ==
OUTLINE_DRAG_MODE &&
currentLoc != null) {
setBoundsForFrame(
f,
currentLoc.
x,
currentLoc.
y,
f.
getWidth(),
f.
getHeight() );
currentLoc = null;
} else if (
dragMode ==
FASTER_DRAG_MODE) {
currentBounds = null;
if (
desktopGraphics != null) {
desktopGraphics.
dispose();
desktopGraphics = null;
}
desktopBounds = null;
((
JInternalFrame)
f).
isDragging = false;
}
}
// implements javax.swing.DesktopManager
public void
beginResizingFrame(
JComponent f, int
direction) {
setupDragMode(
f);
}
/**
* Calls <code>setBoundsForFrame</code> with the new values.
* @param f the component to be resized
* @param newX the new x-coordinate
* @param newY the new y-coordinate
* @param newWidth the new width
* @param newHeight the new height
*/
public void
resizeFrame(
JComponent f, int
newX, int
newY, int
newWidth, int
newHeight) {
if (
dragMode ==
DEFAULT_DRAG_MODE ||
dragMode ==
FASTER_DRAG_MODE ) {
setBoundsForFrame(
f,
newX,
newY,
newWidth,
newHeight);
} else {
JDesktopPane desktopPane =
getDesktopPane(
f);
if (
desktopPane != null){
Graphics g =
JComponent.
safelyGetGraphics(
desktopPane);
g.
setXORMode(
Color.
white);
if (
currentBounds != null) {
g.
drawRect(
currentBounds.
x,
currentBounds.
y,
currentBounds.
width-1,
currentBounds.
height-1);
}
g.
drawRect(
newX,
newY,
newWidth-1,
newHeight-1);
// Work around for 6635462, see comment in dragFrame()
sun.java2d.
SurfaceData sData =
((sun.java2d.
SunGraphics2D)
g).
getSurfaceData();
if (!
sData.
isSurfaceLost()) {
currentBounds = new
Rectangle (
newX,
newY,
newWidth,
newHeight);
}
g.
setPaintMode();
g.
dispose();
}
}
}
// implements javax.swing.DesktopManager
public void
endResizingFrame(
JComponent f) {
if (
dragMode ==
OUTLINE_DRAG_MODE &&
currentBounds != null) {
setBoundsForFrame(
f,
currentBounds.
x,
currentBounds.
y,
currentBounds.
width,
currentBounds.
height );
currentBounds = null;
}
}
/** This moves the <code>JComponent</code> and repaints the damaged areas. */
public void
setBoundsForFrame(
JComponent f, int
newX, int
newY, int
newWidth, int
newHeight) {
f.
setBounds(
newX,
newY,
newWidth,
newHeight);
// we must validate the hierarchy to not break the hw/lw mixing
f.
revalidate();
}
/** Convenience method to remove the desktopIcon of <b>f</b> is necessary. */
protected void
removeIconFor(
JInternalFrame f) {
JInternalFrame.
JDesktopIcon di =
f.
getDesktopIcon();
Container c =
di.
getParent();
if(
c != null) {
c.
remove(
di);
c.
repaint(
di.
getX(),
di.
getY(),
di.
getWidth(),
di.
getHeight());
}
}
/** The iconifyFrame() code calls this to determine the proper bounds
* for the desktopIcon.
*/
protected
Rectangle getBoundsForIconOf(
JInternalFrame f) {
//
// Get the icon for this internal frame and its preferred size
//
JInternalFrame.
JDesktopIcon icon =
f.
getDesktopIcon();
Dimension prefSize =
icon.
getPreferredSize();
//
// Get the parent bounds and child components.
//
Container c =
f.
getParent();
if (
c == null) {
c =
f.
getDesktopIcon().
getParent();
}
if (
c == null) {
/* the frame has not yet been added to the parent; how about (0,0) ?*/
return new
Rectangle(0, 0,
prefSize.
width,
prefSize.
height);
}
Rectangle parentBounds =
c.
getBounds();
Component []
components =
c.
getComponents();
//
// Iterate through valid default icon locations and return the
// first one that does not intersect any other icons.
//
Rectangle availableRectangle = null;
JInternalFrame.
JDesktopIcon currentIcon = null;
int
x = 0;
int
y =
parentBounds.
height -
prefSize.
height;
int
w =
prefSize.
width;
int
h =
prefSize.
height;
boolean
found = false;
while (!
found) {
availableRectangle = new
Rectangle(
x,
y,
w,
h);
found = true;
for ( int
i=0;
i<
components.length;
i++ ) {
//
// Get the icon for this component
//
if (
components[
i] instanceof
JInternalFrame ) {
currentIcon = ((
JInternalFrame)
components[
i]).
getDesktopIcon();
}
else if (
components[
i] instanceof
JInternalFrame.
JDesktopIcon ){
currentIcon = (
JInternalFrame.
JDesktopIcon)
components[
i];
} else
/* found a child that's neither an internal frame nor
an icon. I don't believe this should happen, but at
present it does and causes a null pointer exception.
Even when that gets fixed, this code protects against
the npe. hania */
continue;
//
// If this icon intersects the current location, get next location.
//
if ( !
currentIcon.
equals(
icon) ) {
if (
availableRectangle.
intersects(
currentIcon.
getBounds()) ) {
found = false;
break;
}
}
}
if (
currentIcon == null)
/* didn't find any useful children above. This probably shouldn't
happen, but this check protects against an npe if it ever does
(and it's happening now) */
return
availableRectangle;
x +=
currentIcon.
getBounds().
width;
if (
x +
w >
parentBounds.
width ) {
x = 0;
y -=
h;
}
}
return(
availableRectangle);
}
/**
* Stores the bounds of the component just before a maximize call.
* @param f the component about to be resized
* @param r the normal bounds to be saved away
*/
protected void
setPreviousBounds(
JInternalFrame f,
Rectangle r) {
f.
setNormalBounds(
r);
}
/**
* Gets the normal bounds of the component prior to the component
* being maximized.
* @param f the <code>JInternalFrame</code> of interest
* @return the normal bounds of the component
*/
protected
Rectangle getPreviousBounds(
JInternalFrame f) {
return
f.
getNormalBounds();
}
/**
* Sets that the component has been iconized and the bounds of the
* <code>desktopIcon</code> are valid.
*/
protected void
setWasIcon(
JInternalFrame f,
Boolean value) {
if (
value != null) {
f.
putClientProperty(
HAS_BEEN_ICONIFIED_PROPERTY,
value);
}
}
/**
* Returns <code>true</code> if the component has been iconized
* and the bounds of the <code>desktopIcon</code> are valid,
* otherwise returns <code>false</code>.
*
* @param f the <code>JInternalFrame</code> of interest
* @return <code>true</code> if the component has been iconized;
* otherwise returns <code>false</code>
*/
protected boolean
wasIcon(
JInternalFrame f) {
return (
f.
getClientProperty(
HAS_BEEN_ICONIFIED_PROPERTY) ==
Boolean.
TRUE);
}
JDesktopPane getDesktopPane(
JComponent frame ) {
JDesktopPane pane = null;
Component c =
frame.
getParent();
// Find the JDesktopPane
while (
pane == null ) {
if (
c instanceof
JDesktopPane ) {
pane = (
JDesktopPane)
c;
}
else if (
c == null ) {
break;
}
else {
c =
c.
getParent();
}
}
return
pane;
}
// =========== stuff for faster frame dragging ===================
private void
dragFrameFaster(
JComponent f, int
newX, int
newY) {
Rectangle previousBounds = new
Rectangle(
currentBounds.
x,
currentBounds.
y,
currentBounds.
width,
currentBounds.
height);
// move the frame
currentBounds.
x =
newX;
currentBounds.
y =
newY;
if (
didDrag) {
// Only initiate cleanup if we have actually done a drag.
emergencyCleanup(
f);
}
else {
didDrag = true;
// We reset the danger field as until now we haven't actually
// moved the internal frame so we don't need to initiate repaint.
((
JInternalFrame)
f).
danger = false;
}
boolean
floaterCollision =
isFloaterCollision(
previousBounds,
currentBounds);
JComponent parent = (
JComponent)
f.
getParent();
Rectangle visBounds =
previousBounds.
intersection(
desktopBounds);
RepaintManager currentManager =
RepaintManager.
currentManager(
f);
currentManager.
beginPaint();
try {
if(!
floaterCollision) {
currentManager.
copyArea(
parent,
desktopGraphics,
visBounds.
x,
visBounds.
y,
visBounds.
width,
visBounds.
height,
newX -
previousBounds.
x,
newY -
previousBounds.
y,
true);
}
f.
setBounds(
currentBounds);
if (!
floaterCollision) {
Rectangle r =
currentBounds;
currentManager.
notifyRepaintPerformed(
parent,
r.
x,
r.
y,
r.
width,
r.
height);
}
if(
floaterCollision) {
// since we couldn't blit we just redraw as fast as possible
// the isDragging mucking is to avoid activating emergency
// cleanup
((
JInternalFrame)
f).
isDragging = false;
parent.
paintImmediately(
currentBounds);
((
JInternalFrame)
f).
isDragging = true;
}
// fake out the repaint manager. We'll take care of everything
currentManager.
markCompletelyClean(
parent);
currentManager.
markCompletelyClean(
f);
// compute the minimal newly exposed area
// if the rects intersect then we use computeDifference. Otherwise
// we'll repaint the entire previous bounds
Rectangle[]
dirtyRects = null;
if (
previousBounds.
intersects(
currentBounds) ) {
dirtyRects =
SwingUtilities.
computeDifference(
previousBounds,
currentBounds);
} else {
dirtyRects = new
Rectangle[1];
dirtyRects[0] =
previousBounds;
};
// Fix the damage
for (int
i = 0;
i <
dirtyRects.length;
i++) {
parent.
paintImmediately(
dirtyRects[
i]);
Rectangle r =
dirtyRects[
i];
currentManager.
notifyRepaintPerformed(
parent,
r.
x,
r.
y,
r.
width,
r.
height);
}
// new areas of blit were exposed
if ( !(
visBounds.
equals(
previousBounds)) ) {
dirtyRects =
SwingUtilities.
computeDifference(
previousBounds,
desktopBounds);
for (int
i = 0;
i <
dirtyRects.length;
i++) {
dirtyRects[
i].
x +=
newX -
previousBounds.
x;
dirtyRects[
i].
y +=
newY -
previousBounds.
y;
((
JInternalFrame)
f).
isDragging = false;
parent.
paintImmediately(
dirtyRects[
i]);
((
JInternalFrame)
f).
isDragging = true;
Rectangle r =
dirtyRects[
i];
currentManager.
notifyRepaintPerformed(
parent,
r.
x,
r.
y,
r.
width,
r.
height);
}
}
} finally {
currentManager.
endPaint();
}
// update window if it's non-opaque
Window topLevel =
SwingUtilities.
getWindowAncestor(
f);
Toolkit tk =
Toolkit.
getDefaultToolkit();
if (!
topLevel.
isOpaque() &&
(
tk instanceof
SunToolkit) &&
((
SunToolkit)
tk).
needUpdateWindow())
{
AWTAccessor.
getWindowAccessor().
updateWindow(
topLevel);
}
}
private boolean
isFloaterCollision(
Rectangle moveFrom,
Rectangle moveTo) {
if (
floatingItems.length == 0) {
// System.out.println("no floaters");
return false;
}
for (int
i = 0;
i <
floatingItems.length;
i++) {
boolean
intersectsFrom =
moveFrom.
intersects(
floatingItems[
i]);
if (
intersectsFrom) {
return true;
}
boolean
intersectsTo =
moveTo.
intersects(
floatingItems[
i]);
if (
intersectsTo) {
return true;
}
}
return false;
}
private
Rectangle[]
findFloatingItems(
JComponent f) {
Container desktop =
f.
getParent();
Component[]
children =
desktop.
getComponents();
int
i = 0;
for (
i = 0;
i <
children.length;
i++) {
if (
children[
i] ==
f) {
break;
}
}
// System.out.println(i);
Rectangle[]
floaters = new
Rectangle[
i];
for (
i = 0;
i <
floaters.length;
i++) {
floaters[
i] =
children[
i].
getBounds();
}
return
floaters;
}
/**
* This method is here to clean up problems associated
* with a race condition which can occur when the full contents
* of a copyArea's source argument is not available onscreen.
* This uses brute force to clean up in case of possible damage
*/
private void
emergencyCleanup(final
JComponent f) {
if ( ((
JInternalFrame)
f).
danger ) {
SwingUtilities.
invokeLater( new
Runnable(){
public void
run(){
((
JInternalFrame)
f).
isDragging = false;
f.
paintImmediately(0,0,
f.
getWidth(),
f.
getHeight());
//finalFrame.repaint();
((
JInternalFrame)
f).
isDragging = true;
// System.out.println("repair complete");
}});
((
JInternalFrame)
f).
danger = false;
}
}
}