// // 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) { // 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]); } // 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; } } } 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; } } }Lines 501–807 of 807. Previous lines
// // 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) { // 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]); } // 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; } } } 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; } } }