Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/swing/DefaultDesktopManager.java
38829 views
/*1* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/242526package javax.swing;2728import com.sun.awt.AWTUtilities;29import sun.awt.AWTAccessor;30import sun.awt.SunToolkit;3132import java.awt.*;33import java.beans.PropertyVetoException;3435/** This is an implementation of the <code>DesktopManager</code>.36* It currently implements the basic behaviors for managing37* <code>JInternalFrame</code>s in an arbitrary parent.38* <code>JInternalFrame</code>s that are not children of a39* <code>JDesktop</code> will use this component40* to handle their desktop-like actions.41* <p>This class provides a policy for the various JInternalFrame methods,42* it is not meant to be called directly rather the various JInternalFrame43* methods will call into the DesktopManager.</p>44* @see JDesktopPane45* @see JInternalFrame46* @author David Kloba47* @author Steve Wilson48*/49public class DefaultDesktopManager implements DesktopManager, java.io.Serializable {50final static String HAS_BEEN_ICONIFIED_PROPERTY = "wasIconOnce";5152final static int DEFAULT_DRAG_MODE = 0;53final static int OUTLINE_DRAG_MODE = 1;54final static int FASTER_DRAG_MODE = 2;5556int dragMode = DEFAULT_DRAG_MODE;5758private transient Rectangle currentBounds = null;59private transient Graphics desktopGraphics = null;60private transient Rectangle desktopBounds = null;61private transient Rectangle[] floatingItems = {};6263/**64* Set to true when the user actually drags a frame vs clicks on it65* to start the drag operation. This is only used when dragging with66* FASTER_DRAG_MODE.67*/68private transient boolean didDrag;6970/** Normally this method will not be called. If it is, it71* try to determine the appropriate parent from the desktopIcon of the frame.72* Will remove the desktopIcon from its parent if it successfully adds the frame.73*/74public void openFrame(JInternalFrame f) {75if(f.getDesktopIcon().getParent() != null) {76f.getDesktopIcon().getParent().add(f);77removeIconFor(f);78}79}8081/**82* Removes the frame, and, if necessary, the83* <code>desktopIcon</code>, from its parent.84* @param f the <code>JInternalFrame</code> to be removed85*/86public void closeFrame(JInternalFrame f) {87JDesktopPane d = f.getDesktopPane();88if (d == null) {89return;90}91boolean findNext = f.isSelected();92Container c = f.getParent();93JInternalFrame nextFrame = null;94if (findNext) {95nextFrame = d.getNextFrame(f);96try { f.setSelected(false); } catch (PropertyVetoException e2) { }97}98if(c != null) {99c.remove(f); // Removes the focus.100c.repaint(f.getX(), f.getY(), f.getWidth(), f.getHeight());101}102removeIconFor(f);103if(f.getNormalBounds() != null)104f.setNormalBounds(null);105if(wasIcon(f))106setWasIcon(f, null);107if (nextFrame != null) {108try { nextFrame.setSelected(true); }109catch (PropertyVetoException e2) { }110} else if (findNext && d.getComponentCount() == 0) {111// It was selected and was the last component on the desktop.112d.requestFocus();113}114}115116/**117* Resizes the frame to fill its parents bounds.118* @param f the frame to be resized119*/120public void maximizeFrame(JInternalFrame f) {121if (f.isIcon()) {122try {123// In turn calls deiconifyFrame in the desktop manager.124// That method will handle the maximization of the frame.125f.setIcon(false);126} catch (PropertyVetoException e2) {127}128} else {129f.setNormalBounds(f.getBounds());130Rectangle desktopBounds = f.getParent().getBounds();131setBoundsForFrame(f, 0, 0,132desktopBounds.width, desktopBounds.height);133}134135// Set the maximized frame as selected.136try {137f.setSelected(true);138} catch (PropertyVetoException e2) {139}140}141142/**143* Restores the frame back to its size and position prior144* to a <code>maximizeFrame</code> call.145* @param f the <code>JInternalFrame</code> to be restored146*/147public void minimizeFrame(JInternalFrame f) {148// If the frame was an icon restore it back to an icon.149if (f.isIcon()) {150iconifyFrame(f);151return;152}153154if ((f.getNormalBounds()) != null) {155Rectangle r = f.getNormalBounds();156f.setNormalBounds(null);157try { f.setSelected(true); } catch (PropertyVetoException e2) { }158setBoundsForFrame(f, r.x, r.y, r.width, r.height);159}160}161162/**163* Removes the frame from its parent and adds its164* <code>desktopIcon</code> to the parent.165* @param f the <code>JInternalFrame</code> to be iconified166*/167public void iconifyFrame(JInternalFrame f) {168JInternalFrame.JDesktopIcon desktopIcon;169Container c = f.getParent();170JDesktopPane d = f.getDesktopPane();171boolean findNext = f.isSelected();172desktopIcon = f.getDesktopIcon();173if(!wasIcon(f)) {174Rectangle r = getBoundsForIconOf(f);175desktopIcon.setBounds(r.x, r.y, r.width, r.height);176// we must validate the hierarchy to not break the hw/lw mixing177desktopIcon.revalidate();178setWasIcon(f, Boolean.TRUE);179}180181if (c == null || d == null) {182return;183}184185if (c instanceof JLayeredPane) {186JLayeredPane lp = (JLayeredPane)c;187int layer = lp.getLayer(f);188lp.putLayer(desktopIcon, layer);189}190191// If we are maximized we already have the normal bounds recorded192// don't try to re-record them, otherwise we incorrectly set the193// normal bounds to maximized state.194if (!f.isMaximum()) {195f.setNormalBounds(f.getBounds());196}197d.setComponentOrderCheckingEnabled(false);198c.remove(f);199c.add(desktopIcon);200d.setComponentOrderCheckingEnabled(true);201c.repaint(f.getX(), f.getY(), f.getWidth(), f.getHeight());202if (findNext) {203if (d.selectFrame(true) == null) {204// The icon is the last frame.205f.restoreSubcomponentFocus();206}207}208}209210/**211* Removes the desktopIcon from its parent and adds its frame212* to the parent.213* @param f the <code>JInternalFrame</code> to be de-iconified214*/215public void deiconifyFrame(JInternalFrame f) {216JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon();217Container c = desktopIcon.getParent();218JDesktopPane d = f.getDesktopPane();219if (c != null && d != null) {220c.add(f);221// If the frame is to be restored to a maximized state make222// sure it still fills the whole desktop.223if (f.isMaximum()) {224Rectangle desktopBounds = c.getBounds();225if (f.getWidth() != desktopBounds.width ||226f.getHeight() != desktopBounds.height) {227setBoundsForFrame(f, 0, 0,228desktopBounds.width, desktopBounds.height);229}230}231removeIconFor(f);232if (f.isSelected()) {233f.moveToFront();234f.restoreSubcomponentFocus();235}236else {237try {238f.setSelected(true);239} catch (PropertyVetoException e2) {}240241}242}243}244245/** This will activate <b>f</b> moving it to the front. It will246* set the current active frame's (if any)247* <code>IS_SELECTED_PROPERTY</code> to <code>false</code>.248* There can be only one active frame across all Layers.249* @param f the <code>JInternalFrame</code> to be activated250*/251public void activateFrame(JInternalFrame f) {252Container p = f.getParent();253Component[] c;254JDesktopPane d = f.getDesktopPane();255JInternalFrame currentlyActiveFrame =256(d == null) ? null : d.getSelectedFrame();257// fix for bug: 4162443258if(p == null) {259// If the frame is not in parent, its icon maybe, check it260p = f.getDesktopIcon().getParent();261if(p == null)262return;263}264// we only need to keep track of the currentActive InternalFrame, if any265if (currentlyActiveFrame == null){266if (d != null) { d.setSelectedFrame(f);}267} else if (currentlyActiveFrame != f) {268// if not the same frame as the current active269// we deactivate the current270if (currentlyActiveFrame.isSelected()) {271try {272currentlyActiveFrame.setSelected(false);273}274catch(PropertyVetoException e2) {}275}276if (d != null) { d.setSelectedFrame(f);}277}278f.moveToFront();279}280281// implements javax.swing.DesktopManager282public void deactivateFrame(JInternalFrame f) {283JDesktopPane d = f.getDesktopPane();284JInternalFrame currentlyActiveFrame =285(d == null) ? null : d.getSelectedFrame();286if (currentlyActiveFrame == f)287d.setSelectedFrame(null);288}289290// implements javax.swing.DesktopManager291public void beginDraggingFrame(JComponent f) {292setupDragMode(f);293294if (dragMode == FASTER_DRAG_MODE) {295Component desktop = f.getParent();296floatingItems = findFloatingItems(f);297currentBounds = f.getBounds();298if (desktop instanceof JComponent) {299desktopBounds = ((JComponent)desktop).getVisibleRect();300}301else {302desktopBounds = desktop.getBounds();303desktopBounds.x = desktopBounds.y = 0;304}305desktopGraphics = JComponent.safelyGetGraphics(desktop);306((JInternalFrame)f).isDragging = true;307didDrag = false;308}309310}311312private void setupDragMode(JComponent f) {313JDesktopPane p = getDesktopPane(f);314Container parent = f.getParent();315dragMode = DEFAULT_DRAG_MODE;316if (p != null) {317String mode = (String)p.getClientProperty("JDesktopPane.dragMode");318Window window = SwingUtilities.getWindowAncestor(f);319if (window != null && !AWTUtilities.isWindowOpaque(window)) {320dragMode = DEFAULT_DRAG_MODE;321} else if (mode != null && mode.equals("outline")) {322dragMode = OUTLINE_DRAG_MODE;323} else if (mode != null && mode.equals("faster")324&& f instanceof JInternalFrame325&& ((JInternalFrame)f).isOpaque() &&326(parent == null || parent.isOpaque())) {327dragMode = FASTER_DRAG_MODE;328} else {329if (p.getDragMode() == JDesktopPane.OUTLINE_DRAG_MODE ) {330dragMode = OUTLINE_DRAG_MODE;331} else if ( p.getDragMode() == JDesktopPane.LIVE_DRAG_MODE332&& f instanceof JInternalFrame333&& ((JInternalFrame)f).isOpaque()) {334dragMode = FASTER_DRAG_MODE;335} else {336dragMode = DEFAULT_DRAG_MODE;337}338}339}340}341342private transient Point currentLoc = null;343344/**345* Moves the visible location of the frame being dragged346* to the location specified. The means by which this occurs can vary depending347* on the dragging algorithm being used. The actual logical location of the frame348* might not change until <code>endDraggingFrame</code> is called.349*/350public void dragFrame(JComponent f, int newX, int newY) {351352if (dragMode == OUTLINE_DRAG_MODE) {353JDesktopPane desktopPane = getDesktopPane(f);354if (desktopPane != null){355Graphics g = JComponent.safelyGetGraphics(desktopPane);356357g.setXORMode(Color.white);358if (currentLoc != null) {359g.drawRect(currentLoc.x, currentLoc.y,360f.getWidth()-1, f.getHeight()-1);361}362g.drawRect( newX, newY, f.getWidth()-1, f.getHeight()-1);363/* Work around for 6635462: XOR mode may cause a SurfaceLost on first use.364* Swing doesn't expect that its XOR drawRect did365* not complete, so believes that on re-entering at366* the next update location, that there is an XOR rect367* to draw out at "currentLoc". But in fact368* its now got a new clean surface without that rect,369* so drawing it "out" in fact draws it on, leaving garbage.370* So only update/set currentLoc if the draw completed.371*/372sun.java2d.SurfaceData sData =373((sun.java2d.SunGraphics2D)g).getSurfaceData();374375if (!sData.isSurfaceLost()) {376currentLoc = new Point (newX, newY);377}378;379g.dispose();380}381} else if (dragMode == FASTER_DRAG_MODE) {382dragFrameFaster(f, newX, newY);383} else {384setBoundsForFrame(f, newX, newY, f.getWidth(), f.getHeight());385}386}387388// implements javax.swing.DesktopManager389public void endDraggingFrame(JComponent f) {390if ( dragMode == OUTLINE_DRAG_MODE && currentLoc != null) {391setBoundsForFrame(f, currentLoc.x, currentLoc.y, f.getWidth(), f.getHeight() );392currentLoc = null;393} else if (dragMode == FASTER_DRAG_MODE) {394currentBounds = null;395if (desktopGraphics != null) {396desktopGraphics.dispose();397desktopGraphics = null;398}399desktopBounds = null;400((JInternalFrame)f).isDragging = false;401}402}403404// implements javax.swing.DesktopManager405public void beginResizingFrame(JComponent f, int direction) {406setupDragMode(f);407}408409/**410* Calls <code>setBoundsForFrame</code> with the new values.411* @param f the component to be resized412* @param newX the new x-coordinate413* @param newY the new y-coordinate414* @param newWidth the new width415* @param newHeight the new height416*/417public void resizeFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {418419if ( dragMode == DEFAULT_DRAG_MODE || dragMode == FASTER_DRAG_MODE ) {420setBoundsForFrame(f, newX, newY, newWidth, newHeight);421} else {422JDesktopPane desktopPane = getDesktopPane(f);423if (desktopPane != null){424Graphics g = JComponent.safelyGetGraphics(desktopPane);425426g.setXORMode(Color.white);427if (currentBounds != null) {428g.drawRect( currentBounds.x, currentBounds.y, currentBounds.width-1, currentBounds.height-1);429}430g.drawRect( newX, newY, newWidth-1, newHeight-1);431432// Work around for 6635462, see comment in dragFrame()433sun.java2d.SurfaceData sData =434((sun.java2d.SunGraphics2D)g).getSurfaceData();435if (!sData.isSurfaceLost()) {436currentBounds = new Rectangle (newX, newY, newWidth, newHeight);437}438439g.setPaintMode();440g.dispose();441}442}443444}445446// implements javax.swing.DesktopManager447public void endResizingFrame(JComponent f) {448if ( dragMode == OUTLINE_DRAG_MODE && currentBounds != null) {449setBoundsForFrame(f, currentBounds.x, currentBounds.y, currentBounds.width, currentBounds.height );450currentBounds = null;451}452}453454455/** This moves the <code>JComponent</code> and repaints the damaged areas. */456public void setBoundsForFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {457f.setBounds(newX, newY, newWidth, newHeight);458// we must validate the hierarchy to not break the hw/lw mixing459f.revalidate();460}461462/** Convenience method to remove the desktopIcon of <b>f</b> is necessary. */463protected void removeIconFor(JInternalFrame f) {464JInternalFrame.JDesktopIcon di = f.getDesktopIcon();465Container c = di.getParent();466if(c != null) {467c.remove(di);468c.repaint(di.getX(), di.getY(), di.getWidth(), di.getHeight());469}470}471472/** The iconifyFrame() code calls this to determine the proper bounds473* for the desktopIcon.474*/475476protected Rectangle getBoundsForIconOf(JInternalFrame f) {477//478// Get the icon for this internal frame and its preferred size479//480481JInternalFrame.JDesktopIcon icon = f.getDesktopIcon();482Dimension prefSize = icon.getPreferredSize();483//484// Get the parent bounds and child components.485//486487Container c = f.getParent();488if (c == null) {489c = f.getDesktopIcon().getParent();490}491492if (c == null) {493/* the frame has not yet been added to the parent; how about (0,0) ?*/494return new Rectangle(0, 0, prefSize.width, prefSize.height);495}496497Rectangle parentBounds = c.getBounds();498Component [] components = c.getComponents();499500501//502// Iterate through valid default icon locations and return the503// first one that does not intersect any other icons.504//505506Rectangle availableRectangle = null;507JInternalFrame.JDesktopIcon currentIcon = null;508509int x = 0;510int y = parentBounds.height - prefSize.height;511int w = prefSize.width;512int h = prefSize.height;513514boolean found = false;515516while (!found) {517518availableRectangle = new Rectangle(x,y,w,h);519520found = true;521522for ( int i=0; i<components.length; i++ ) {523524//525// Get the icon for this component526//527528if ( components[i] instanceof JInternalFrame ) {529currentIcon = ((JInternalFrame)components[i]).getDesktopIcon();530}531else if ( components[i] instanceof JInternalFrame.JDesktopIcon ){532currentIcon = (JInternalFrame.JDesktopIcon)components[i];533} else534/* found a child that's neither an internal frame nor535an icon. I don't believe this should happen, but at536present it does and causes a null pointer exception.537Even when that gets fixed, this code protects against538the npe. hania */539continue;540541//542// If this icon intersects the current location, get next location.543//544545if ( !currentIcon.equals(icon) ) {546if ( availableRectangle.intersects(currentIcon.getBounds()) ) {547found = false;548break;549}550}551}552553if (currentIcon == null)554/* didn't find any useful children above. This probably shouldn't555happen, but this check protects against an npe if it ever does556(and it's happening now) */557return availableRectangle;558559x += currentIcon.getBounds().width;560561if ( x + w > parentBounds.width ) {562x = 0;563y -= h;564}565}566567return(availableRectangle);568}569570/**571* Stores the bounds of the component just before a maximize call.572* @param f the component about to be resized573* @param r the normal bounds to be saved away574*/575protected void setPreviousBounds(JInternalFrame f, Rectangle r) {576f.setNormalBounds(r);577}578579/**580* Gets the normal bounds of the component prior to the component581* being maximized.582* @param f the <code>JInternalFrame</code> of interest583* @return the normal bounds of the component584*/585protected Rectangle getPreviousBounds(JInternalFrame f) {586return f.getNormalBounds();587}588589/**590* Sets that the component has been iconized and the bounds of the591* <code>desktopIcon</code> are valid.592*/593protected void setWasIcon(JInternalFrame f, Boolean value) {594if (value != null) {595f.putClientProperty(HAS_BEEN_ICONIFIED_PROPERTY, value);596}597}598599/**600* Returns <code>true</code> if the component has been iconized601* and the bounds of the <code>desktopIcon</code> are valid,602* otherwise returns <code>false</code>.603*604* @param f the <code>JInternalFrame</code> of interest605* @return <code>true</code> if the component has been iconized;606* otherwise returns <code>false</code>607*/608protected boolean wasIcon(JInternalFrame f) {609return (f.getClientProperty(HAS_BEEN_ICONIFIED_PROPERTY) == Boolean.TRUE);610}611612613JDesktopPane getDesktopPane( JComponent frame ) {614JDesktopPane pane = null;615Component c = frame.getParent();616617// Find the JDesktopPane618while ( pane == null ) {619if ( c instanceof JDesktopPane ) {620pane = (JDesktopPane)c;621}622else if ( c == null ) {623break;624}625else {626c = c.getParent();627}628}629630return pane;631}632633634// =========== stuff for faster frame dragging ===================635636private void dragFrameFaster(JComponent f, int newX, int newY) {637638Rectangle previousBounds = new Rectangle(currentBounds.x,639currentBounds.y,640currentBounds.width,641currentBounds.height);642643// move the frame644currentBounds.x = newX;645currentBounds.y = newY;646647if (didDrag) {648// Only initiate cleanup if we have actually done a drag.649emergencyCleanup(f);650}651else {652didDrag = true;653// We reset the danger field as until now we haven't actually654// moved the internal frame so we don't need to initiate repaint.655((JInternalFrame)f).danger = false;656}657658boolean floaterCollision = isFloaterCollision(previousBounds, currentBounds);659660JComponent parent = (JComponent)f.getParent();661Rectangle visBounds = previousBounds.intersection(desktopBounds);662663RepaintManager currentManager = RepaintManager.currentManager(f);664665currentManager.beginPaint();666try {667if(!floaterCollision) {668currentManager.copyArea(parent, desktopGraphics, visBounds.x,669visBounds.y,670visBounds.width,671visBounds.height,672newX - previousBounds.x,673newY - previousBounds.y,674true);675}676677f.setBounds(currentBounds);678679if (!floaterCollision) {680Rectangle r = currentBounds;681currentManager.notifyRepaintPerformed(parent, r.x, r.y, r.width, r.height);682}683684if(floaterCollision) {685// since we couldn't blit we just redraw as fast as possible686// the isDragging mucking is to avoid activating emergency687// cleanup688((JInternalFrame)f).isDragging = false;689parent.paintImmediately(currentBounds);690((JInternalFrame)f).isDragging = true;691}692693// fake out the repaint manager. We'll take care of everything694695currentManager.markCompletelyClean(parent);696currentManager.markCompletelyClean(f);697698// compute the minimal newly exposed area699// if the rects intersect then we use computeDifference. Otherwise700// we'll repaint the entire previous bounds701Rectangle[] dirtyRects = null;702if ( previousBounds.intersects(currentBounds) ) {703dirtyRects = SwingUtilities.computeDifference(previousBounds,704currentBounds);705} else {706dirtyRects = new Rectangle[1];707dirtyRects[0] = previousBounds;708};709710// Fix the damage711for (int i = 0; i < dirtyRects.length; i++) {712parent.paintImmediately(dirtyRects[i]);713Rectangle r = dirtyRects[i];714currentManager.notifyRepaintPerformed(parent, r.x, r.y, r.width, r.height);715}716717// new areas of blit were exposed718if ( !(visBounds.equals(previousBounds)) ) {719dirtyRects = SwingUtilities.computeDifference(previousBounds,720desktopBounds);721for (int i = 0; i < dirtyRects.length; i++) {722dirtyRects[i].x += newX - previousBounds.x;723dirtyRects[i].y += newY - previousBounds.y;724((JInternalFrame)f).isDragging = false;725parent.paintImmediately(dirtyRects[i]);726((JInternalFrame)f).isDragging = true;727Rectangle r = dirtyRects[i];728currentManager.notifyRepaintPerformed(parent, r.x, r.y, r.width, r.height);729}730731}732} finally {733currentManager.endPaint();734}735736// update window if it's non-opaque737Window topLevel = SwingUtilities.getWindowAncestor(f);738Toolkit tk = Toolkit.getDefaultToolkit();739if (!topLevel.isOpaque() &&740(tk instanceof SunToolkit) &&741((SunToolkit)tk).needUpdateWindow())742{743AWTAccessor.getWindowAccessor().updateWindow(topLevel);744}745}746747private boolean isFloaterCollision(Rectangle moveFrom, Rectangle moveTo) {748if (floatingItems.length == 0) {749// System.out.println("no floaters");750return false;751}752753for (int i = 0; i < floatingItems.length; i++) {754boolean intersectsFrom = moveFrom.intersects(floatingItems[i]);755if (intersectsFrom) {756return true;757}758boolean intersectsTo = moveTo.intersects(floatingItems[i]);759if (intersectsTo) {760return true;761}762}763764return false;765}766767private Rectangle[] findFloatingItems(JComponent f) {768Container desktop = f.getParent();769Component[] children = desktop.getComponents();770int i = 0;771for (i = 0; i < children.length; i++) {772if (children[i] == f) {773break;774}775}776// System.out.println(i);777Rectangle[] floaters = new Rectangle[i];778for (i = 0; i < floaters.length; i++) {779floaters[i] = children[i].getBounds();780}781782return floaters;783}784785/**786* This method is here to clean up problems associated787* with a race condition which can occur when the full contents788* of a copyArea's source argument is not available onscreen.789* This uses brute force to clean up in case of possible damage790*/791private void emergencyCleanup(final JComponent f) {792793if ( ((JInternalFrame)f).danger ) {794795SwingUtilities.invokeLater( new Runnable(){796public void run(){797798((JInternalFrame)f).isDragging = false;799f.paintImmediately(0,0,800f.getWidth(),801f.getHeight());802803//finalFrame.repaint();804((JInternalFrame)f).isDragging = true;805// System.out.println("repair complete");806}});807808((JInternalFrame)f).danger = false;809}810811}812813814}815816817