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

Save This Page
Home » openjdk-7 » javax » swing » [javadoc | source]