Source Code Cross Referenced for DockPanel.java in  » XML-UI » xui32 » com » blogofbug » swing » components » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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 geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML UI » xui32 » com.blogofbug.swing.components 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * DockPanel.java
003:         *
004:         * Created on January 9, 2007, 6:22 AM
005:         *
006:         * Re-implementation of the dock to use a grid-bag-laid-out panel instead
007:         * of the very complicated code I was developing.
008:         *
009:         * Copyright 2006-2007 Nigel Hughes 
010:         *
011:         * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
012:         * in compliance with the License. You may obtain a copy of the License at http://www.apache.org/
013:         * licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software 
014:         * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
015:         * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language 
016:         * governing permissions and limitations under the License.
017:         */
018:
019:        package com.blogofbug.swing.components;
020:
021:        import com.blogofbug.swing.SwingBugUtilities;
022:        import com.blogofbug.swing.components.effects.ComponentEffect;
023:        import com.blogofbug.swing.components.effects.ComponentTextEffect;
024:        import com.blogofbug.swing.components.effects.ContainerEffectManager;
025:        import com.blogofbug.swing.components.effects.EffectContainer;
026:        import com.blogofbug.swing.delegates.MouseTracker;
027:        import com.blogofbug.swing.delegates.MouseTrackerListener;
028:        import java.awt.Color;
029:        import java.awt.Component;
030:        import java.awt.Container;
031:        import java.awt.Dimension;
032:        import java.awt.Graphics;
033:        import java.awt.GridBagConstraints;
034:        import java.awt.GridBagLayout;
035:        import java.awt.Point;
036:        import java.awt.Rectangle;
037:        import java.awt.event.ActionEvent;
038:        import java.awt.event.ActionListener;
039:        import java.awt.event.ComponentEvent;
040:        import java.awt.event.ComponentListener;
041:        import java.util.Hashtable;
042:        import javax.swing.JComponent;
043:        import javax.swing.JPanel;
044:        import javax.swing.Timer;
045:        import java.awt.Insets;
046:
047:        /**
048:         * A dock that can be added to the glass pane of a frame
049:         * @author nigel
050:         */
051:        public class DockPanel extends JPanel implements  MouseTrackerListener,
052:                ActionListener, ContainerEffectManager.ComponentEffectSupplier {
053:            /**
054:             * Enumeration object to contain the side of the screen/window the dock is against
055:             *
056:             */
057:            public enum Side {
058:                /**
059:                 * Lock dock to top of the window
060:                 */
061:                NORTH,
062:                /**
063:                 * Lock the dock to the bottom of the window
064:                 */
065:                SOUTH,
066:                /**
067:                 * Locks the dock to the right of the dock
068:                 */
069:                EAST,
070:                /**
071:                 * Lock the dock to the left of the window
072:                 */
073:                WEST
074:            };
075:
076:            //The enlarged size of the icons
077:            /**
078:             * The "mouse over" size of a dock entry
079:             */
080:            private int enlargedSize = 96;
081:
082:            //The normal size of the icons
083:            /**
084:             * The "mouse out" size
085:             */
086:            private int normalSize = 32;
087:
088:            //Insets around each dock icon
089:            /**
090:             * The insets around the dock
091:             */
092:            private int insets = 2;
093:
094:            //The side the dock is docked to
095:            /**
096:             * The frame the dock is associated with
097:             */
098:            private Side dockedTo = Side.SOUTH;
099:
100:            //Autohide?
101:            /**
102:             * Should the dock automatically hide when the mouse is outside of the area
103:             */
104:            private boolean autoHide = false;
105:
106:            //Auto-hiding!
107:            /**
108:             * True if the dock is currently being hidden
109:             */
110:            private boolean hiding = false;
111:
112:            //Layout and standard constraints
113:            /**
114:             * The layout being used for the container
115:             */
116:            private GridBagLayout layout = new GridBagLayout();
117:            /**
118:             * The constraint for the filler objects
119:             */
120:            private GridBagConstraints filler = new GridBagConstraints();
121:            /**
122:             * The constraints for the title object
123:             */
124:            private GridBagConstraints title = new GridBagConstraints();
125:            /**
126:             * The constraints for an icon in the dock...
127:             */
128:            private GridBagConstraints icon = new GridBagConstraints();
129:
130:            /**
131:             * Spacer object above the dock
132:             */
133:            protected JSpacer spacer;;
134:            /**
135:             * Spacer on the "left" of the dock
136:             */
137:            protected JSpacer firstSpacer;;
138:            /**
139:             * Spacer on the right of the dock
140:             */
141:            protected JSpacer lastSpacer;
142:
143:            /**
144:             * Controls whether or not autohiding is already on a trigger
145:             */
146:            protected boolean delayedAutoHide = false;
147:
148:            /** 
149:             * Determines current in/out status
150:             */
151:            protected boolean couldAutoHide = false;
152:
153:            /**
154:             * Hold index of components and their titles
155:             */
156:            private Hashtable<Component, String> iconLabels = new Hashtable<Component, String>();
157:
158:            /**
159:             * Track mouse movements (will be over the entire component)
160:             */
161:            private MouseTracker mouseTracker;
162:
163:            /**
164:             * Animation timer
165:             */
166:            //private Timer               timer = new Timer(0,this);
167:            /**
168:             * Records in an animation is currently planning
169:             */
170:            private boolean animating = false;
171:
172:            private int minHidingSize = 16;
173:
174:            //Mouse location (last known)
175:            /**
176:             * Last known location of the mouse
177:             */
178:            private Point lastKnownMouse = new Point(0, 0);
179:
180:            private boolean returnToNormal = true;
181:            private boolean overDockComponent = false;
182:            private boolean normalTimerRunning = false;
183:
184:            /** 
185:             * Effects for the dock components
186:             */
187:            protected ContainerEffectManager effects = new ContainerEffectManager(
188:                    this , this , true);
189:
190:            /**
191:             * Debug mode
192:             */
193:            private static final boolean DEBUG_MODE = true;
194:
195:            /**
196:             * Creates a new instance of DockPanel
197:             * @param normalSize The normal size of the dock icons
198:             * @param enlargedSize The "mouse over" size of the dock icons
199:             * @param dockedTo The side the dock is attached to
200:             */
201:            public DockPanel(int normalSize, int enlargedSize, Side dockedTo) {
202:                //Set up the basics
203:                this .dockedTo = dockedTo;
204:                this .enlargedSize = enlargedSize;
205:                this .normalSize = normalSize;
206:
207:                //Prepare the timer
208:                //        timer.setCoalesce(true);
209:                //        timer.setDelay(20);
210:                //        timer.setRepeats(true);
211:                //        timer.start();
212:                startTimer();
213:                addComponentListener(new ComponentListener() {
214:                    public void componentHidden(ComponentEvent componentEvent) {
215:                        stopTimer();
216:                    }
217:
218:                    public void componentMoved(ComponentEvent componentEvent) {
219:                    }
220:
221:                    public void componentResized(ComponentEvent componentEvent) {
222:                    }
223:
224:                    public void componentShown(ComponentEvent componentEvent) {
225:                        startTimer();
226:                    }
227:                });
228:
229:                //make me transparent
230:                setBackground(null);
231:                setOpaque(false);
232:
233:                //Set up the mouse tracker
234:                mouseTracker = new MouseTracker(this , this );
235:
236:                //Set up the spacers
237:                spacer = new JSpacer();
238:                firstSpacer = new JSpacer();
239:                lastSpacer = new JSpacer();
240:
241:                //Initial setup
242:                setLayout(layout);
243:                initializeLayout();
244:                add(spacer, filler);
245:                add(firstSpacer, icon);
246:                add(lastSpacer, icon);
247:
248:                //Perform initial layout
249:                updateLayout(null);
250:            }
251:
252:            private void startTimer() {
253:                SwingBugUtilities.addTimerListener(this );
254:            }
255:
256:            private void stopTimer() {
257:                SwingBugUtilities.removeTimerListener(this );
258:            }
259:
260:            /**
261:             * Determines if the dock is currently hiding (or hidden)
262:             * @return True if it is auto-hiding...
263:             */
264:            public boolean isAutoHiding() {
265:                return autoHide;
266:            }
267:
268:            /**
269:             * Turns auto-hiding on or off
270:             * @param autoHide True to turn it on, false to turn it off
271:             */
272:            public void setAutoHiding(boolean autoHide) {
273:                this .autoHide = autoHide;
274:                mouseMoved(lastKnownMouse);
275:            }
276:
277:            /**
278:             * Creates a new instance of the dock which will attach to the south of the frame
279:             * @param normalSize The normal size of the icon
280:             * @param enlargedSize The mouse-over size of icons in the dock
281:             */
282:            public DockPanel(int normalSize, int enlargedSize) {
283:                this (normalSize, enlargedSize, Side.SOUTH);
284:            }
285:
286:            /**
287:             * Sets the normal size of an icon in the dock
288:             * @param normalSize The normal size. 
289:             */
290:            public void setNormalSize(int normalSize) {
291:                this .normalSize = normalSize;
292:                updateLayout(null);
293:                layout.layoutContainer(this );
294:            }
295:
296:            /**
297:             * Sets the minimum dimension of the hidden component
298:             * @param minSize The minimum dimension. 
299:             */
300:            public void setMinHidingSize(int minSize) {
301:                minHidingSize = minSize;
302:            }
303:
304:            /**
305:             * Sets the mouse-over size of an icon in the dock
306:             * @param enlargedSize The enlarged size
307:             */
308:            public void setEnlargedSize(int enlargedSize) {
309:                this .enlargedSize = enlargedSize;
310:                updateLayout(null);
311:                layout.layoutContainer(this );
312:            }
313:
314:            /**
315:             * Sets up the basic layout and then calls updateLayout to finalize the
316:             * individual dock elements
317:             */
318:            private void initializeLayout() {
319:                //Standard settings for the filler panel
320:                filler.fill = GridBagConstraints.BOTH;
321:                filler.weightx = 1.0;
322:                filler.weighty = 1.0;
323:
324:                //Standard settings for the title components
325:                title.anchor = GridBagConstraints.CENTER;
326:
327:                //Standard settings for the icon components
328:                icon.anchor = GridBagConstraints.CENTER;
329:                icon.weightx = 0.0;
330:                icon.weighty = 0.0;
331:                icon.insets = new Insets(insets / 2, insets / 2, insets / 2,
332:                        insets / 2);
333:
334:                //Do various bits of specific constraints layout
335:                switch (dockedTo) {
336:                case SOUTH:
337:                    filler.gridx = 0;
338:                    filler.gridy = 0;
339:                    filler.gridheight = 1;
340:                    filler.gridwidth = GridBagConstraints.REMAINDER;
341:                    title.gridx = 0;
342:                    title.gridy = 1;
343:                    icon.gridx = 0;
344:                    icon.gridy = 2;
345:                    icon.anchor = GridBagConstraints.SOUTH;
346:                    break;
347:                case NORTH:
348:                    filler.gridx = 0;
349:                    filler.gridy = 2;
350:                    filler.gridheight = 1;
351:                    filler.gridwidth = GridBagConstraints.REMAINDER;
352:                    title.gridx = 0;
353:                    title.gridy = 1;
354:                    icon.gridx = 0;
355:                    icon.gridy = 0;
356:                    icon.anchor = GridBagConstraints.NORTH;
357:                    break;
358:                case WEST:
359:                    filler.gridx = 2;
360:                    filler.gridy = 0;
361:                    filler.gridheight = GridBagConstraints.REMAINDER;
362:                    filler.gridwidth = 1;
363:                    title.gridx = 1;
364:                    title.gridy = 0;
365:                    icon.gridx = 0;
366:                    icon.gridy = 0;
367:                    icon.anchor = GridBagConstraints.WEST;
368:                    break;
369:                case EAST:
370:                    filler.gridx = 0;
371:                    filler.gridy = 0;
372:                    filler.gridheight = GridBagConstraints.REMAINDER;
373:                    filler.gridwidth = 1;
374:                    title.gridx = 1;
375:                    title.gridy = 0;
376:                    icon.gridx = 2;
377:                    icon.gridy = 0;
378:                    icon.anchor = GridBagConstraints.EAST;
379:                    break;
380:                }
381:            }
382:
383:            /**
384:             * Changes the side of the panel the dock is attached to
385:             * @param dockedTo Determines the side of the frame the dock is connected to 
386:             */
387:            public void setDockedTo(DockPanel.Side dockedTo) {
388:                this .dockedTo = dockedTo;
389:                initializeLayout();
390:                layout.setConstraints(spacer, filler);
391:                updateLayout(null);
392:                layout.layoutContainer(this );
393:            }
394:
395:            /**
396:             * Determines the appropriate gridbag weight for the "book-end" spacers
397:             * at either end of the dock
398:             *
399:             * @return The weight
400:             */
401:            private double spacerWeightX() {
402:                switch (dockedTo) {
403:                case NORTH:
404:                case SOUTH:
405:                    return 1.0;
406:                case EAST:
407:                case WEST:
408:                    return 0.0;
409:                }
410:                return 0.0;
411:            }
412:
413:            /**
414:             * Determines the appropriate gridbag weight for the "book-end" spacers
415:             * at either end of the dock
416:             *
417:             * @return The weight
418:             */
419:            private double spacerWeightY() {
420:                return 1.0 - spacerWeightX();
421:            }
422:
423:            /**
424:             * Determines the appropriate size for the component based on the current "mouse over"
425:             * component, the location in the dock area relative to the overall dock panel, and a given component
426:             * This is protected so it can be over-ridden to apply a better alogrithm .
427:             *
428:             * @param p The location of the mouse relative to the overall dock
429:             * @param component The component to be sized
430:             * @param highlightedComponent The current component with the mouse over it
431:             * @return A Dimension object with the recommened size of the component
432:             */
433:            protected Dimension getComponentPreferedSize(Point p,
434:                    Component component, Component highlightedComponent) {
435:                //If we are hiding it should be small
436:                if (hiding) {
437:                    int size = Math.max(insets * 3, minHidingSize);
438:                    return new Dimension(size, size);
439:                }
440:
441:                //determine it's distance based on half the size of the biggest component
442:                double compSize = component.getSize().height;
443:                double distanceFromCenter = 0;
444:                double delta = (double) (enlargedSize - normalSize);
445:
446:                if ((highlightedComponent != null)) {
447:                    switch (dockedTo) {
448:                    case NORTH:
449:                    case SOUTH:
450:                        distanceFromCenter = Math.abs((double) ((component
451:                                .getLocation().x + compSize / 2) - p.x));
452:                        break;
453:                    case EAST:
454:                    case WEST:
455:                        distanceFromCenter = Math.abs((double) ((component
456:                                .getLocation().y + compSize / 2) - p.y));
457:                        break;
458:                    }
459:
460:                    //            if (highlightedComponent==component){
461:                    if (distanceFromCenter < enlargedSize / 2) {
462:                        return new Dimension(enlargedSize, enlargedSize);
463:                    }
464:
465:                    double cdy = 1.0 - distanceFromCenter
466:                            / (double) (enlargedSize * 2);
467:                    double tSize = Math.max((double) normalSize + cdy * delta,
468:                            (double) normalSize);
469:                    int size = (int) tSize;
470:
471:                    return new Dimension(size, size);
472:                } else {
473:                    if (returnToNormal) {
474:                        return new Dimension(normalSize, normalSize);
475:                    } else {
476:                        return component.getPreferredSize();
477:                    }
478:                }
479:            }
480:
481:            /**
482:             * Essentially removes the spacer that forces the dock to the bottom of the
483:             * panel, neat if you would like to use the panel as something like a
484:             * special tab top.
485:             *
486:             * @param fillSpace true if the panel should fill up any empty space above the dock,
487:             * false if it should not
488:             */
489:            public void fillSpace(boolean fillSpace) {
490:                spacer.setVisible(fillSpace);
491:            }
492:
493:            /**
494:             * Determines a value between the current and target including easing. Can
495:             * be over-ridden if desired to have different sizing behavior. Implementers 
496:             * should note that if the size is not clipped to ensure that the icons will
497:             * all fit in the dock, gridbag does Bad Things (tm). 
498:             *
499:             * @param current The current value
500:             * @param target  The target value
501:             * @return A value equal to or between target and current
502:             */
503:            protected double tweenValue(double current, double target) {
504:                //Just make sure we do nothing if they are the same
505:                if (current == target) {
506:                    return target;
507:                }
508:
509:                //Determine the difference
510:                double delta = (target - current) / 8.0;
511:
512:                //Tween in the right direction, but always by at least one pixel
513:                if (delta > 0) {
514:                    delta = Math.max(1.0, delta);
515:                } else if (delta < 0) {
516:                    delta = Math.min(-1.0, delta);
517:                }
518:
519:                switch (dockedTo) {
520:                case SOUTH:
521:                case NORTH:
522:                    return Math.min(current + delta, (getWidth() - insets
523:                            * iconLabels.size() * 2)
524:                            / iconLabels.size() - 10);
525:                default:
526:                    return Math.min(current + delta, (getHeight() - insets
527:                            * iconLabels.size() * 2)
528:                            / iconLabels.size());
529:                }
530:            }
531:
532:            /**
533:             * Determines if a component is in the dock
534:             * @param component The component you wish to test to see if its in the dock
535:             * @return True if it does, false if it doesn't
536:             */
537:            public boolean dockContains(Component component) {
538:                if (iconLabels.get(component) != null) {
539:                    return true;
540:                }
541:                return false;
542:            }
543:
544:            /**
545:             * Takes a current size, and determines a new size setting up an animation
546:             * if needed.
547:             *
548:             * @param currentSize The current size of the component
549:             * @param newSize     The new size of the component
550:             * @return The in-between size
551:             */
552:            private Dimension tweenSize(Dimension currentSize, Dimension newSize) {
553:                if ((newSize.width != currentSize.width)
554:                        || (newSize.height != currentSize.height)) {
555:                    animating = true;
556:                    newSize.width = (int) tweenValue(currentSize.width,
557:                            newSize.width);
558:                    newSize.height = (int) tweenValue(currentSize.height,
559:                            newSize.height);
560:                }
561:                return newSize;
562:            }
563:
564:            /**
565:             * 
566:             *
567:             */
568:            private void setReturnToNormal() {
569:                if (returnToNormal) {
570:                    return;
571:                }
572:                normalTimerRunning = true;
573:                SwingBugUtilities.invokeAfter(new Runnable() {
574:                    public void run() {
575:                        if (!overDockComponent) {
576:                            returnToNormal = true;
577:                            normalTimerRunning = false;
578:                            validate();
579:                        }
580:                    }
581:                }, 100);
582:            }
583:
584:            /** 
585:             * Debug method
586:             * 
587:             * @param component The component
588:             */
589:            protected void showComponentLabel(JComponent component, String text) {
590:                //Debugging information
591:                if (DEBUG_MODE) {
592:                    ComponentEffect ce = effects
593:                            .getEffectFor((JComponent) component);
594:                    if ((ce != null) && (ce instanceof  ComponentTextEffect)) {
595:                        ((ComponentTextEffect) ce).setText(text);
596:                    }
597:                }
598:            }
599:
600:            /**
601:             * Determines the new settings for the gridbag layout, and then applies them
602:             * to all components
603:             * @param p The point the mouse is at
604:             */
605:            private void updateLayout(Point p) {
606:                Component highlightedComponent = null;
607:                animating = false;
608:                if (p != null) {
609:                    highlightedComponent = getComponentAt(p);
610:                    //Make sure it's at least in the dock zone
611:                    switch (dockedTo) {
612:                    case NORTH:
613:                        if (p.y > spacer.getY()) {
614:                            highlightedComponent = null;
615:                        }
616:                        break;
617:                    case SOUTH:
618:                        if (p.y < spacer.getHeight()) {
619:                            highlightedComponent = null;
620:                        }
621:                        break;
622:                    case WEST:
623:                        if (p.x > spacer.getX()) {
624:                            highlightedComponent = null;
625:                        }
626:                        break;
627:                    case EAST:
628:                        if (p.x < spacer.getWidth()) {
629:                            highlightedComponent = null;
630:                        }
631:                        break;
632:                    }
633:                    if ((highlightedComponent == firstSpacer)
634:                            || (highlightedComponent == lastSpacer)) {
635:                        highlightedComponent = null;
636:                    }
637:                }
638:                //Variables used for incrementing grid-x's and grid-y's
639:                int dx = 0, dy = 0;
640:                switch (dockedTo) {
641:                case NORTH:
642:                case SOUTH:
643:                    dx = 1;
644:                    break;
645:                case EAST:
646:                case WEST:
647:                    dy = 1;
648:                    break;
649:                }
650:
651:                //Set everything up as it should be
652:                initializeLayout();
653:
654:                //Add first spacer and move to next position
655:                icon.weightx = spacerWeightX();
656:                icon.weighty = spacerWeightY();
657:                icon.fill = GridBagConstraints.BOTH;
658:                layout.setConstraints(firstSpacer, icon);
659:                icon.fill = GridBagConstraints.NONE;
660:                icon.gridx += dx;
661:                icon.gridy += dy;
662:                title.gridx += dx;
663:                title.gridy += dy;
664:
665:                if (highlightedComponent == null) {
666:                    setReturnToNormal();
667:                    overDockComponent = false;
668:                } else {
669:                    overDockComponent = true;
670:                    returnToNormal = false;
671:                }
672:
673:                //Iterate through the components updating everything
674:                Component[] components = getComponents();
675:                for (Component component : components) {
676:                    //Make sure it's not a filler or a title
677:                    if (!((component == spacer)
678:                            || (component instanceof  DockLabel)
679:                            || (component == firstSpacer) || (component == lastSpacer))) {
680:                        //Set the weight
681:                        icon.weightx = 0.0;
682:                        icon.weighty = 0.0;
683:                        //Icon first
684:                        layout.setConstraints(component, icon);
685:
686:                        //Set the prefered size of the component
687:                        component.setPreferredSize(tweenSize(component
688:                                .getSize(), getComponentPreferedSize(p,
689:                                component, highlightedComponent)));
690:
691:                        //Set the visibility of its label
692:                        if (highlightedComponent == component) {
693:                            showComponentLabel((JComponent) component,
694:                                    iconLabels.get(component));
695:                        } else {
696:                            showComponentLabel((JComponent) component, "");
697:                        }
698:
699:                        //Move to next position
700:                        icon.gridx += dx;
701:                        icon.gridy += dy;
702:                        title.gridx += dx;
703:                        title.gridy += dy;
704:                    }
705:                }
706:
707:                //Add the last spacer
708:                icon.weightx = spacerWeightX();
709:                icon.weighty = spacerWeightY();
710:                icon.fill = GridBagConstraints.BOTH;
711:                layout.setConstraints(lastSpacer, icon);
712:            }
713:
714:            /**
715:             * Adds a new item to the dock
716:             * @param component The component to add
717:             * @param label The label to display when the mouse is over the dock item
718:             */
719:            public void addDockElement(Component component, String label) {
720:                if (iconLabels.get(component) != null) {
721:                    return;
722:                }
723:
724:                //We would like it to do something funcky as it adds them and make them grow
725:                component.setPreferredSize(new Dimension(0, 0));
726:                iconLabels.put(component, label);
727:                add(component);
728:                updateLayout(mouseTracker.getPosition());
729:            }
730:
731:            /**
732:             * Not interested
733:             * @param mouseEntered True if the mouse came in 
734:             */
735:            public void mouseCrossThreshold(boolean mouseEntered) {
736:            }
737:
738:            /** 
739:             * Fires an auto-hide check after a delay to ensure the mouse didn't just
740:             * stray out of the dock on the way from one place to another. 
741:             */
742:            protected void delayedAutoHide() {
743:                if (delayedAutoHide) {
744:                    return;
745:                }
746:                delayedAutoHide = true;
747:                SwingBugUtilities.invokeAfter(new Runnable() {
748:                    public void run() {
749:                        hiding = couldAutoHide;
750:                        if (hiding) {
751:                            validate();
752:                        }
753:                        delayedAutoHide = false;
754:                    }
755:                }, 1000);
756:            }
757:
758:            /**
759:             * When the mouse moves, update the layout. Should be optimized when the
760:             * highlighted component is the spacer to not do anything
761:             * @param position The location of the mouse
762:             */
763:            public void mouseMoved(Point position) {
764:                if (autoHide) {
765:                    Component mouseOver = getComponentAt(position);
766:                    final Component self = this ;
767:                    if ((mouseOver == firstSpacer) || (mouseOver == lastSpacer)
768:                            || (spacer == mouseOver) || (mouseOver == this )) {
769:                        couldAutoHide = true;
770:                        if (hiding == false) {
771:                            delayedAutoHide();
772:                        }
773:                    } else {
774:                        hiding = false;
775:                        couldAutoHide = false;
776:                    }
777:                } else {
778:                    hiding = false;
779:                    couldAutoHide = false;
780:                }
781:                lastKnownMouse = position;
782:                updateLayout(position);
783:                layout.layoutContainer(this );
784:            }
785:
786:            /**
787:             * Returns true if the mouse is over a dock component, but false at all other times. This will cause
788:             * swing to pass on the event to the next layer down.
789:             * @param x The frame relative dock location x-cordination
790:             * @param y The frame relative dock location y-coordinate
791:             * @return True if the mouse is over a dock icon, false otherwise
792:             */
793:            public boolean contains(int x, int y) {
794:                Rectangle rect = new Rectangle();
795:                //Have to implement our own componentAt here
796:                for (Component comp : getComponents()) {
797:                    rect = comp.getBounds(rect);
798:                    if (rect.contains(x, y)) {
799:                        if (comp instanceof  JSpacer) {
800:                            //                    System.out.println("Out");
801:                            mouseMoved(new Point(-1, -1));
802:                            return false;
803:                        }
804:                        //                System.out.println("In");
805:                        return true;
806:                    }
807:                }
808:                //A little non-intuitive. If it's not over a normal component or a spacer, it's in the dock area
809:                return true;
810:            }
811:
812:            protected void paintChildren(Graphics graphics) {
813:                super .paintChildren(graphics);
814:                if (DEBUG_MODE) {
815:                    effects.paintEffects(graphics);
816:                }
817:            }
818:
819:            /**
820:             * Paints the component.
821:             *
822:             * @param graphics The graphics context
823:             */
824:            public void paintComponent(Graphics graphics) {
825:                graphics.setColor(getBackground());
826:                Rectangle dockSize = null;
827:                int oldNormalSize = normalSize;
828:                if (hiding) {
829:                    normalSize = Math
830:                            .min(
831:                                    normalSize,
832:                                    ((dockedTo == Side.NORTH) || (dockedTo == Side.SOUTH)) ? firstSpacer
833:                                            .getHeight()
834:                                            : firstSpacer.getWidth());
835:                    normalSize = Math.max(normalSize, minHidingSize);
836:                }
837:                //Draw the main dock background
838:                switch (dockedTo) {
839:                case NORTH:
840:                    dockSize = new Rectangle(firstSpacer.getX()
841:                            + firstSpacer.getWidth(), 0, getWidth()
842:                            - (lastSpacer.getWidth() + firstSpacer.getWidth()),
843:                            normalSize);
844:                    break;
845:                case SOUTH:
846:                    dockSize = new Rectangle(firstSpacer.getX()
847:                            + firstSpacer.getWidth(), getHeight() - normalSize,
848:                            getWidth()
849:                                    - (lastSpacer.getWidth() + firstSpacer
850:                                            .getWidth()), normalSize);
851:                    break;
852:                case WEST:
853:                    dockSize = new Rectangle(0, firstSpacer.getHeight(),
854:                            normalSize, getHeight()
855:                                    - (lastSpacer.getHeight() + firstSpacer
856:                                            .getHeight()));
857:                    break;
858:                case EAST:
859:                    dockSize = new Rectangle(getWidth() - normalSize,
860:                            firstSpacer.getHeight(), normalSize, getHeight()
861:                                    - (lastSpacer.getHeight() + firstSpacer
862:                                            .getHeight()));
863:                    break;
864:                }
865:                if (hiding) {
866:                    normalSize = oldNormalSize;
867:                }
868:
869:                dockSize.x -= insets;
870:                dockSize.y -= insets;
871:                dockSize.width += insets * 2;
872:                dockSize.height += insets * 2;
873:                graphics.fillRect(dockSize.x, dockSize.y, dockSize.width,
874:                        dockSize.height);
875:
876:                //Draw the outline
877:                graphics.setColor(new Color(255, 255, 255, 127));
878:                switch (dockedTo) {
879:                case SOUTH:
880:                    graphics.drawRect(dockSize.x, dockSize.y,
881:                            dockSize.width - 1, dockSize.height);
882:                    break;
883:                }
884:                super .paintComponent(graphics);
885:            }
886:
887:            /**
888:             * Called when the animation timer fires
889:             * @param actionEvent The action event
890:             */
891:            public void actionPerformed(ActionEvent actionEvent) {
892:                if (animating) {
893:                    updateLayout(lastKnownMouse);
894:                    layout.layoutContainer(this );
895:                }
896:            }
897:
898:            public ComponentEffect getEffect(JComponent forComponent,
899:                    Container inComponent, EffectContainer effectEngine) {
900:                if (this .DEBUG_MODE) {
901:                    if (forComponent instanceof  JSpacer) {
902:                        return null;
903:                    } else {
904:                        return new ComponentTextEffect(inComponent,
905:                                forComponent, effectEngine, "",
906:                                ComponentTextEffect.TextLocation.NORTH);
907:                    }
908:                }
909:                return null;
910:            }
911:
912:            //For convenience
913:            /**
914:             * A utilitity class to fill the gaps around the dock contents
915:             */
916:            public class JSpacer extends JComponent {
917:                /**
918:                 * Creates a new instance of the dock spacer
919:                 */
920:                public JSpacer() {
921:                    setBackground(null);
922:                    setOpaque(false);
923:                }
924:
925:            }
926:
927:            //Temporary until I do something else
928:            /**
929:             * A utiliity class to represent the label of the currently mouse-over dock item
930:             */
931:            public class DockLabel extends StrokedLabel {
932:                /**
933:                 * Creats a new instance of the dock label
934:                 * @param title The text of the label
935:                 */
936:                public DockLabel(String title) {
937:                    super(title);
938:                }
939:
940:            };
941:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.