Source Code Cross Referenced for ViewTooltips.java in  » IDE-Netbeans » openide » org » openide » explorer » view » 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 » IDE Netbeans » openide » org.openide.explorer.view 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003:         *
004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * The contents of this file are subject to the terms of either the GNU
007:         * General Public License Version 2 only ("GPL") or the Common
008:         * Development and Distribution License("CDDL") (collectively, the
009:         * "License"). You may not use this file except in compliance with the
010:         * License. You can obtain a copy of the License at
011:         * http://www.netbeans.org/cddl-gplv2.html
012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013:         * specific language governing permissions and limitations under the
014:         * License.  When distributing the software, include this License Header
015:         * Notice in each file and include the License file at
016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
017:         * particular file as subject to the "Classpath" exception as provided
018:         * by Sun in the GPL Version 2 section of the License file that
019:         * accompanied this code. If applicable, add the following below the
020:         * License Header, with the fields enclosed by brackets [] replaced by
021:         * your own identifying information:
022:         * "Portions Copyrighted [year] [name of copyright owner]"
023:         *
024:         * Contributor(s):
025:         *
026:         * The Original Software is NetBeans. The Initial Developer of the Original
027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028:         * Microsystems, Inc. All Rights Reserved.
029:         *
030:         * If you wish your version of this file to be governed by only the CDDL
031:         * or only the GPL Version 2, indicate your decision by adding
032:         * "[Contributor] elects to include this software in this distribution
033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
034:         * single choice of license, a recipient has the option to distribute
035:         * your version of this file under either the CDDL, the GPL Version 2 or
036:         * to extend the choice of license to its licensees as provided above.
037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
038:         * Version 2 license, then the option applies only if the new code is
039:         * made subject to such option by the copyright holder.
040:         */
041:
042:        package org.openide.explorer.view;
043:
044:        import java.awt.Color;
045:        import java.awt.Component;
046:        import java.awt.Dimension;
047:        import java.awt.Graphics;
048:        import java.awt.Graphics2D;
049:        import java.awt.Insets;
050:        import java.awt.KeyboardFocusManager;
051:        import java.awt.Point;
052:        import java.awt.Rectangle;
053:        import java.awt.event.ComponentEvent;
054:        import java.awt.event.ComponentListener;
055:        import java.awt.event.HierarchyBoundsListener;
056:        import java.awt.event.HierarchyEvent;
057:        import java.awt.event.HierarchyListener;
058:        import java.awt.event.MouseAdapter;
059:        import java.awt.event.MouseEvent;
060:        import java.awt.event.MouseMotionListener;
061:        import java.awt.geom.AffineTransform;
062:        import java.awt.image.BufferedImage;
063:        import java.beans.PropertyChangeEvent;
064:        import java.beans.PropertyChangeListener;
065:        import javax.swing.JComponent;
066:        import javax.swing.JList;
067:        import javax.swing.JScrollPane;
068:        import javax.swing.JTree;
069:        import javax.swing.ListCellRenderer;
070:        import javax.swing.Popup;
071:        import javax.swing.PopupFactory;
072:        import javax.swing.SwingUtilities;
073:        import javax.swing.border.Border;
074:        import javax.swing.event.ChangeEvent;
075:        import javax.swing.event.ChangeListener;
076:        import javax.swing.event.ListDataEvent;
077:        import javax.swing.event.ListDataListener;
078:        import javax.swing.event.ListSelectionEvent;
079:        import javax.swing.event.ListSelectionListener;
080:        import javax.swing.event.TreeModelEvent;
081:        import javax.swing.event.TreeModelListener;
082:        import javax.swing.event.TreeSelectionEvent;
083:        import javax.swing.event.TreeSelectionListener;
084:        import javax.swing.tree.TreePath;
085:        import org.openide.util.Lookup;
086:        import org.openide.util.Utilities;
087:
088:        /**
089:         * Displays pseudo-tooltips for tree and list views which don't have enough
090:         * space.  This class is not NB specific, and can be used with any
091:         * JTree or JList.
092:         *
093:         * @author Tim Boudreau
094:         */
095:        final class ViewTooltips extends MouseAdapter implements 
096:                MouseMotionListener {
097:            /** The default instance, reference counted */
098:            private static ViewTooltips INSTANCE = null;
099:            /** A reference count for number of comps listened to */
100:            private int refcount = 0;
101:            /** The last known component we were invoked against, nulled on hide() */
102:            private JComponent inner = null;
103:            /** The last row we were invoked against */
104:            private int row = -1;
105:            /** An array of currently visible popups */
106:            private Popup[] popups = new Popup[2];
107:            /** A component we'll reuse to paint into the popups */
108:            private ImgComp painter = new ImgComp();
109:
110:            /** Nobody should instantiate this */
111:            private ViewTooltips() {
112:            }
113:
114:            /**
115:             * Register a child of a JScrollPane (only JList or JTree supported 
116:             * for now) which should show helper tooltips.  Should be called
117:             * from the component's addNotify() method.
118:             */
119:            static void register(JComponent comp) {
120:                if (INSTANCE == null) {
121:                    INSTANCE = new ViewTooltips();
122:                }
123:                INSTANCE.attachTo(comp);
124:            }
125:
126:            /**
127:             * Unregister a child of a JScrollPane (only JList or JTree supported 
128:             * for now) which should show helper tooltips. Should be called
129:             * from the component's removeNotify() method.
130:             */
131:            static void unregister(JComponent comp) {
132:                assert INSTANCE != null : "Unregister asymmetrically called";
133:                if (INSTANCE.detachFrom(comp) == 0) {
134:                    INSTANCE.hide();
135:                    INSTANCE = null;
136:                }
137:            }
138:
139:            /** Start listening to mouse motion on the passed component */
140:            private void attachTo(JComponent comp) {
141:                assert comp instanceof  JTree || comp instanceof  JList;
142:                comp.addMouseListener(this );
143:                comp.addMouseMotionListener(this );
144:                refcount++;
145:            }
146:
147:            /** Stop listening to mouse motion on the passed component */
148:            private int detachFrom(JComponent comp) {
149:                assert comp instanceof  JTree || comp instanceof  JList;
150:                comp.removeMouseMotionListener(this );
151:                comp.removeMouseListener(this );
152:                return refcount--;
153:            }
154:
155:            public void mouseMoved(MouseEvent e) {
156:                Point p = e.getPoint();
157:                JComponent comp = (JComponent) e.getSource();
158:                JScrollPane jsp = (JScrollPane) SwingUtilities
159:                        .getAncestorOfClass(JScrollPane.class, comp);
160:                if (jsp != null) {
161:                    p = SwingUtilities.convertPoint(comp, p, jsp);
162:                    show(jsp, p);
163:                }
164:            }
165:
166:            public void mouseDragged(MouseEvent e) {
167:                hide();
168:            }
169:
170:            public void mouseEntered(MouseEvent e) {
171:                hide();
172:            }
173:
174:            public void mouseExited(MouseEvent e) {
175:                hide();
176:            }
177:
178:            /** Shows the appropriate popups given the state of the scroll pane and
179:             * its view. 
180:             * @param view The scroll pane owning the component the event happened on
181:             * @param pt The point at which the mouse event happened, in the coordinate
182:             *  space of the scroll pane.
183:             */
184:            void show(JScrollPane view, Point pt) {
185:                if (view.getViewport().getView() instanceof  JTree) {
186:                    showJTree(view, pt);
187:                } else if (view.getViewport().getView() instanceof  JList) {
188:                    showJList(view, pt);
189:                } else {
190:                    assert false : "Bad component type registered: "
191:                            + view.getViewport().getView();
192:                }
193:            }
194:
195:            private void showJList(JScrollPane view, Point pt) {
196:                JList list = (JList) view.getViewport().getView();
197:                Point p = SwingUtilities.convertPoint(view, pt.x, pt.y, list);
198:                int row = list.locationToIndex(p);
199:                if (row == -1) {
200:                    hide();
201:                    return;
202:                }
203:                Rectangle bds = list.getCellBounds(row, row);
204:                //GetCellBounds returns a width that is the
205:                //full component width;  we want only what
206:                //the renderer really needs.
207:                ListCellRenderer ren = list.getCellRenderer();
208:                Dimension rendererSize = ren.getListCellRendererComponent(list,
209:                        list.getModel().getElementAt(row), row, false, false)
210:                        .getPreferredSize();
211:
212:                bds.width = rendererSize.width;
213:                if (bds == null || !bds.contains(p)) {
214:                    hide();
215:                    return;
216:                }
217:                if (setCompAndRow(list, row)) {
218:                    Rectangle visible = getShowingRect(view);
219:                    Rectangle[] rects = getRects(bds, visible);
220:                    if (rects.length > 0) {
221:                        ensureOldPopupsHidden();
222:                        painter.configure(list.getModel().getElementAt(row),
223:                                view, list, row);
224:                        showPopups(rects, bds, visible, list, view);
225:                    } else {
226:                        hide();
227:                    }
228:                }
229:            }
230:
231:            private void showJTree(JScrollPane view, Point pt) {
232:                JTree tree = (JTree) view.getViewport().getView();
233:                Point p = SwingUtilities.convertPoint(view, pt.x, pt.y, tree);
234:
235:                int row = tree.getClosestRowForLocation(p.x, p.y);
236:
237:                TreePath path = tree.getClosestPathForLocation(p.x, p.y);
238:
239:                Rectangle bds = tree.getPathBounds(path);
240:                if (bds == null || !bds.contains(p)) {
241:                    hide();
242:                    return;
243:                }
244:                if (setCompAndRow(tree, row)) {
245:                    Rectangle visible = getShowingRect(view);
246:                    Rectangle[] rects = getRects(bds, visible);
247:                    if (rects.length > 0) {
248:                        ensureOldPopupsHidden();
249:                        painter.configure(path.getLastPathComponent(), view,
250:                                tree, path, row);
251:                        showPopups(rects, bds, visible, tree, view);
252:                    } else {
253:                        hide();
254:                    }
255:                }
256:            }
257:
258:            /**
259:             * Set the currently shown component and row, returning true if they are
260:             * not the same as the last known values.
261:             */
262:            private boolean setCompAndRow(JComponent inner, int row) {
263:                boolean rowChanged = row != this .row;
264:                boolean compChanged = inner != this .inner;
265:                this .inner = inner;
266:                this .row = row;
267:                return (rowChanged || compChanged);
268:            }
269:
270:            /**
271:             * Hide all popups and discard any references to the components the
272:             * popups were showing for.
273:             */
274:            void hide() {
275:                ensureOldPopupsHidden();
276:                if (painter != null) {
277:                    painter.clear();
278:                }
279:                setHideComponent(null, null);
280:                inner = null;
281:                row = -1;
282:            }
283:
284:            private void ensureOldPopupsHidden() {
285:                for (int i = 0; i < popups.length; i++) {
286:                    if (popups[i] != null) {
287:                        popups[i].hide();
288:                        popups[i] = null;
289:                    }
290:                }
291:            }
292:
293:            /**
294:             * Gets the sub-rectangle of a JScrollPane's area that
295:             * is actually showing the view
296:             */
297:            private Rectangle getShowingRect(JScrollPane pane) {
298:                Insets ins1 = pane.getViewport().getInsets();
299:                Border inner = pane.getViewportBorder();
300:                Insets ins2;
301:                if (inner != null) {
302:                    ins2 = inner.getBorderInsets(pane);
303:                } else {
304:                    ins2 = new Insets(0, 0, 0, 0);
305:                }
306:                Insets ins3 = new Insets(0, 0, 0, 0);
307:                if (pane.getBorder() != null) {
308:                    ins3 = pane.getBorder().getBorderInsets(pane);
309:                }
310:
311:                Rectangle r = pane.getViewportBorderBounds();
312:                r.translate(-r.x, -r.y);
313:                r.width -= ins1.left + ins1.right;
314:                r.width -= ins2.left + ins2.right;
315:                r.height -= ins1.top + ins1.bottom;
316:                r.height -= ins2.top + ins2.bottom;
317:                r.x -= ins2.left;
318:                r.x -= ins3.left;
319:                Point p = pane.getViewport().getViewPosition();
320:                r.translate(p.x, p.y);
321:                r = SwingUtilities
322:                        .convertRectangle(pane.getViewport(), r, pane);
323:                return r;
324:            }
325:
326:            /**
327:             * Fetches an array or rectangles representing the non-overlapping
328:             * portions of a cell rect against the visible portion of the component.
329:             * @bds The cell's bounds, in the coordinate space of the tree or list
330:             * @vis The visible area of the tree or list, in the tree or list's coordinate space
331:             */
332:            private static final Rectangle[] getRects(final Rectangle bds,
333:                    final Rectangle vis) {
334:                Rectangle[] result;
335:                if (vis.contains(bds)) {
336:                    result = new Rectangle[0];
337:                } else {
338:                    if (bds.x < vis.x && bds.x + bds.width > vis.x + vis.width) {
339:                        Rectangle a = new Rectangle(bds.x, bds.y,
340:                                vis.x - bds.x, bds.height);
341:                        Rectangle b = new Rectangle(vis.x + vis.width, bds.y,
342:                                (bds.x + bds.width) - (vis.x + vis.width),
343:                                bds.height);
344:                        result = new Rectangle[] { a, b };
345:                    } else if (bds.x < vis.x) {
346:                        result = new Rectangle[] { new Rectangle(bds.x, bds.y,
347:                                vis.x - bds.x, bds.height) };
348:                    } else if (bds.x + bds.width > vis.x + vis.width) {
349:                        result = new Rectangle[] { new Rectangle(vis.x
350:                                + vis.width, bds.y, (bds.x + bds.width)
351:                                - (vis.x + vis.width), bds.height) };
352:                    } else {
353:                        result = new Rectangle[0];
354:                    }
355:                }
356:                return result;
357:            }
358:
359:            /**
360:             * Show popups for each rectangle, using the now configured painter.
361:             */
362:            private void showPopups(Rectangle[] rects, Rectangle bds,
363:                    Rectangle visible, JComponent comp, JScrollPane view) {
364:                boolean shown = false;
365:                for (int i = 0; i < rects.length; i++) {
366:                    Rectangle sect = rects[i];
367:                    sect.translate(-bds.x, -bds.y);
368:                    ImgComp part = painter.getPartial(sect,
369:                            bds.x + rects[i].x < visible.x);
370:                    Point pos = new Point(bds.x + rects[i].x, bds.y
371:                            + rects[i].y);
372:                    SwingUtilities.convertPointToScreen(pos, comp);
373:                    if (comp instanceof  JList) {
374:                        //XXX off by one somewhere, only with JLists - where?
375:                        pos.y--;
376:                    }
377:                    if (pos.x > 0) { //Mac OS will reposition off-screen popups to x=0,
378:                        //so don't try to show them
379:                        popups[i] = getPopupFactory().getPopup(view, part,
380:                                pos.x, pos.y);
381:                        popups[i].show();
382:                        shown = true;
383:                    }
384:                }
385:                if (shown) {
386:                    setHideComponent(comp, view);
387:                } else {
388:                    setHideComponent(null, null); //clear references
389:                }
390:            }
391:
392:            private static PopupFactory getPopupFactory() {
393:                if (Utilities.isMac()) {
394:
395:                    // See ide/applemenu/src/org/netbeans/modules/applemenu/ApplePopupFactory
396:                    // We have a custom PopupFactory that will consistently use 
397:                    // lightweight popups on Mac OS, since HW popups get a drop
398:                    // shadow.  By default, popups returned when a heavyweight popup
399:                    // is needed (SDI mode) are no-op popups, since some hacks
400:                    // are necessary to make it really work.
401:
402:                    // To enable heavyweight popups which have no drop shadow
403:                    // *most* of the time on mac os, run with
404:                    // -J-Dnb.explorer.hw.completions=true
405:
406:                    // To enable heavyweight popups which have no drop shadow 
407:                    // *ever* on mac os, you need to put the cocoa classes on the
408:                    // classpath - modify netbeans.conf to add 
409:                    // System/Library/Java on the bootclasspath.  *Then*
410:                    // run with the above line switch and 
411:                    // -J-Dnb.explorer.hw.cocoahack=true
412:
413:                    PopupFactory result = (PopupFactory) Lookup.getDefault()
414:                            .lookup(PopupFactory.class);
415:                    return result == null ? PopupFactory.getSharedInstance()
416:                            : result;
417:                } else {
418:                    return PopupFactory.getSharedInstance();
419:                }
420:            }
421:
422:            private Hider hider = null;
423:
424:            /**
425:             * Set a component (JList or JTree) which should be listened to, such that if
426:             * a model, selection or scroll event occurs, all currently open popups
427:             * should be hidden.
428:             */
429:            private void setHideComponent(JComponent comp, JScrollPane parent) {
430:                if (hider != null) {
431:                    if (hider.isListeningTo(comp)) {
432:                        return;
433:                    }
434:                }
435:                if (hider != null) {
436:                    hider.detach();
437:                }
438:                if (comp != null) {
439:                    hider = new Hider(comp, parent);
440:                } else {
441:                    hider = null;
442:                }
443:            }
444:
445:            /**
446:             * A JComponent which creates a BufferedImage of a cell renderer and can
447:             * produce clones of itself that display subrectangles of that cell
448:             * renderer.
449:             */
450:            private static final class ImgComp extends JComponent {
451:                private BufferedImage img;
452:                private Dimension d = null;
453:
454:                private Color bg = Color.WHITE;
455:                private JScrollPane comp = null;
456:
457:                private Object node = null;
458:
459:                private AffineTransform at = AffineTransform
460:                        .getTranslateInstance(0d, 0d);
461:                boolean isRight = false;
462:
463:                ImgComp() {
464:                }
465:
466:                /**
467:                 * Create a clone with a specified backing image
468:                 */
469:                ImgComp(BufferedImage img, Rectangle off, boolean right) {
470:                    this .img = img;
471:                    at = AffineTransform.getTranslateInstance(-off.x, 0);
472:                    d = new Dimension(off.width, off.height);
473:                    isRight = right;
474:                }
475:
476:                public ImgComp getPartial(Rectangle bds, boolean right) {
477:                    assert img != null;
478:                    return new ImgComp(img, bds, right);
479:                }
480:
481:                /** Configures a tree cell renderer and sets up sizing and the 
482:                 * backing image from it */
483:                public boolean configure(Object nd, JScrollPane tv, JTree tree,
484:                        TreePath path, int row) {
485:                    boolean sameVn = setLastRendereredObject(nd);
486:                    boolean sameComp = setLastRenderedScrollPane(tv);
487:                    Component renderer = null;
488:                    bg = tree.getBackground();
489:                    boolean sel = tree.isSelectionEmpty() ? false : tree
490:                            .getSelectionModel().isPathSelected(path);
491:                    boolean exp = tree.isExpanded(path);
492:                    boolean leaf = !exp && tree.getModel().isLeaf(nd);
493:                    boolean lead = path.equals(tree.getSelectionModel()
494:                            .getLeadSelectionPath());
495:                    renderer = tree.getCellRenderer()
496:                            .getTreeCellRendererComponent(tree, nd, sel, exp,
497:                                    leaf, row, lead);
498:                    if (renderer != null) {
499:                        setComponent(renderer);
500:                    }
501:                    return true;
502:                }
503:
504:                /** Configures a list cell renderer and sets up sizing and the 
505:                 * backing image from it */
506:                public boolean configure(Object nd, JScrollPane tv, JList list,
507:                        int row) {
508:                    boolean sameVn = setLastRendereredObject(nd);
509:                    boolean sameComp = setLastRenderedScrollPane(tv);
510:                    Component renderer = null;
511:                    bg = list.getBackground();
512:                    boolean sel = list.isSelectionEmpty() ? false : list
513:                            .getSelectionModel().isSelectedIndex(row);
514:                    renderer = list.getCellRenderer()
515:                            .getListCellRendererComponent(list, nd, row, sel,
516:                                    false);
517:                    if (renderer != null) {
518:                        setComponent(renderer);
519:                    }
520:                    return true;
521:                }
522:
523:                private boolean setLastRenderedScrollPane(JScrollPane comp) {
524:                    boolean result = comp != this .comp;
525:                    this .comp = comp;
526:                    return result;
527:                }
528:
529:                private boolean setLastRendereredObject(Object nd) {
530:                    boolean result = node != nd;
531:                    if (result) {
532:                        node = nd;
533:                    }
534:                    return result;
535:                }
536:
537:                void clear() {
538:                    comp = null;
539:                    node = null;
540:                }
541:
542:                /**
543:                 * Set the cell renderer we will proxy.
544:                 */
545:                public void setComponent(Component jc) {
546:                    Dimension d = jc.getPreferredSize();
547:                    BufferedImage nue = new BufferedImage(d.width,
548:                            d.height + 2, BufferedImage.TYPE_INT_ARGB_PRE);
549:                    SwingUtilities.paintComponent(nue.getGraphics(), jc, this ,
550:                            0, 0, d.width, d.height + 2);
551:                    setImage(nue);
552:                }
553:
554:                public Rectangle getBounds() {
555:                    Dimension dd = getPreferredSize();
556:                    return new Rectangle(0, 0, dd.width, dd.height);
557:                }
558:
559:                private void setImage(BufferedImage img) {
560:                    this .img = img;
561:                    d = null;
562:                }
563:
564:                public Dimension getPreferredSize() {
565:                    if (d == null) {
566:                        d = new Dimension(img.getWidth(), img.getHeight());
567:                    }
568:                    return d;
569:                }
570:
571:                public Dimension getSize() {
572:                    return getPreferredSize();
573:                }
574:
575:                public void paint(Graphics g) {
576:                    g.setColor(bg);
577:                    g.fillRect(0, 0, d.width, d.height);
578:                    Graphics2D g2d = (Graphics2D) g;
579:                    g2d.drawRenderedImage(img, at);
580:                    g.setColor(Color.GRAY);
581:                    g.drawLine(0, 0, d.width, 0);
582:                    g.drawLine(0, d.height - 1, d.width, d.height - 1);
583:                    if (isRight) {
584:                        g.drawLine(0, 0, 0, d.height - 1);
585:                    } else {
586:                        g.drawLine(d.width - 1, 0, d.width - 1, d.height - 1);
587:                    }
588:                }
589:
590:                public void firePropertyChange(String s, Object a, Object b) {
591:                }
592:
593:                public void invalidate() {
594:                }
595:
596:                public void validate() {
597:                }
598:
599:                public void revalidate() {
600:                }
601:            }
602:
603:            /**
604:             * A listener that listens to just about everything in the known universe
605:             * and hides all currently displayed popups if anything happens.
606:             */
607:            private static final class Hider implements  ChangeListener,
608:                    PropertyChangeListener, TreeModelListener,
609:                    TreeSelectionListener, HierarchyListener,
610:                    HierarchyBoundsListener, ListSelectionListener,
611:                    ListDataListener, ComponentListener {
612:                private final JTree tree;
613:
614:                private JScrollPane pane;
615:                private final JList list;
616:
617:                public Hider(JComponent comp, JScrollPane pane) {
618:                    if (comp instanceof  JTree) {
619:                        this .tree = (JTree) comp;
620:                        this .list = null;
621:                    } else {
622:                        this .list = (JList) comp;
623:                        this .tree = null;
624:                    }
625:                    assert tree != null || list != null;
626:                    this .pane = pane;
627:                    attach();
628:                }
629:
630:                private boolean isListeningTo(JComponent comp) {
631:                    return !detached && (comp == list || comp == tree);
632:                }
633:
634:                private void attach() {
635:                    if (tree != null) {
636:                        tree.getModel().addTreeModelListener(this );
637:                        tree.getSelectionModel().addTreeSelectionListener(this );
638:                        tree.addHierarchyBoundsListener(this );
639:                        tree.addHierarchyListener(this );
640:                        tree.addComponentListener(this );
641:                    } else {
642:                        list.getSelectionModel().addListSelectionListener(this );
643:                        list.getModel().addListDataListener(this );
644:                        list.addHierarchyBoundsListener(this );
645:                        list.addHierarchyListener(this );
646:                        list.addComponentListener(this );
647:                    }
648:                    pane.getHorizontalScrollBar().getModel().addChangeListener(
649:                            this );
650:                    pane.getVerticalScrollBar().getModel().addChangeListener(
651:                            this );
652:                    KeyboardFocusManager.getCurrentKeyboardFocusManager()
653:                            .addPropertyChangeListener(this );
654:                }
655:
656:                private boolean detached = false;
657:
658:                private void detach() {
659:                    KeyboardFocusManager.getCurrentKeyboardFocusManager()
660:                            .removePropertyChangeListener(this );
661:                    if (tree != null) {
662:                        tree.getSelectionModel().removeTreeSelectionListener(
663:                                this );
664:                        tree.getModel().removeTreeModelListener(this );
665:                        tree.removeHierarchyBoundsListener(this );
666:                        tree.removeHierarchyListener(this );
667:                        tree.removeComponentListener(this );
668:                    } else {
669:                        list.getSelectionModel().removeListSelectionListener(
670:                                this );
671:                        list.getModel().removeListDataListener(this );
672:                        list.removeHierarchyBoundsListener(this );
673:                        list.removeHierarchyListener(this );
674:                        list.removeComponentListener(this );
675:                    }
676:                    pane.getHorizontalScrollBar().getModel()
677:                            .removeChangeListener(this );
678:                    pane.getVerticalScrollBar().getModel()
679:                            .removeChangeListener(this );
680:                    detached = true;
681:                }
682:
683:                private void change() {
684:                    if (ViewTooltips.INSTANCE != null) {
685:                        ViewTooltips.INSTANCE.hide();
686:                    }
687:                    detach();
688:                }
689:
690:                public void propertyChange(PropertyChangeEvent evt) {
691:                    change();
692:                }
693:
694:                public void treeNodesChanged(TreeModelEvent e) {
695:                    change();
696:                }
697:
698:                public void treeNodesInserted(TreeModelEvent e) {
699:                    change();
700:                }
701:
702:                public void treeNodesRemoved(TreeModelEvent e) {
703:                    change();
704:                }
705:
706:                public void treeStructureChanged(TreeModelEvent e) {
707:                    change();
708:                }
709:
710:                public void hierarchyChanged(HierarchyEvent e) {
711:                    change();
712:                }
713:
714:                public void valueChanged(TreeSelectionEvent e) {
715:                    change();
716:                }
717:
718:                public void ancestorMoved(HierarchyEvent e) {
719:                    change();
720:                }
721:
722:                public void ancestorResized(HierarchyEvent e) {
723:                    change();
724:                }
725:
726:                public void stateChanged(ChangeEvent e) {
727:                    change();
728:                }
729:
730:                public void valueChanged(ListSelectionEvent e) {
731:                    change();
732:                }
733:
734:                public void intervalAdded(ListDataEvent e) {
735:                    change();
736:                }
737:
738:                public void intervalRemoved(ListDataEvent e) {
739:                    change();
740:                }
741:
742:                public void contentsChanged(ListDataEvent e) {
743:                    change();
744:                }
745:
746:                public void componentResized(ComponentEvent e) {
747:                    change();
748:                }
749:
750:                public void componentMoved(ComponentEvent e) {
751:                    change();
752:                }
753:
754:                public void componentShown(ComponentEvent e) {
755:                    change();
756:                }
757:
758:                public void componentHidden(ComponentEvent e) {
759:                    change();
760:                }
761:            }
762:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.