Source Code Cross Referenced for DefaultDesktopManager.java in  » 6.0-JDK-Core » swing » javax » swing » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » swing » javax.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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