Source Code Cross Referenced for JidePopup.java in  » Swing-Library » jide-common » com » jidesoft » popup » 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 » Swing Library » jide common » com.jidesoft.popup 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * @(#)JidePopup.java 2/24/2005
0003:         *
0004:         * Copyright 2002 - 2005 JIDE Software Inc. All rights reserved.
0005:         */
0006:
0007:        package com.jidesoft.popup;
0008:
0009:        import com.jidesoft.plaf.LookAndFeelFactory;
0010:        import com.jidesoft.plaf.PopupUI;
0011:        import com.jidesoft.plaf.UIDefaultsLookup;
0012:        import com.jidesoft.swing.JideScrollPane;
0013:        import com.jidesoft.swing.JideSwingUtilities;
0014:        import com.jidesoft.swing.Resizable;
0015:        import com.jidesoft.swing.ResizableWindow;
0016:        import com.jidesoft.utils.PortingUtils;
0017:        import com.jidesoft.utils.SecurityUtils;
0018:        import sun.awt.EmbeddedFrame;
0019:
0020:        import javax.accessibility.Accessible;
0021:        import javax.accessibility.AccessibleContext;
0022:        import javax.accessibility.AccessibleRole;
0023:        import javax.accessibility.AccessibleValue;
0024:        import javax.swing.*;
0025:        import javax.swing.border.Border;
0026:        import javax.swing.event.PopupMenuEvent;
0027:        import javax.swing.event.PopupMenuListener;
0028:        import java.applet.Applet;
0029:        import java.awt.*;
0030:        import java.awt.event.*;
0031:        import java.util.ArrayList;
0032:        import java.util.List;
0033:
0034:        /**
0035:         * <code>JidePopup</code> is a popup window which can be resized, dragged and autohide if time out.
0036:         * <p/>
0037:         * JidePopup uses JWindow as the container in order to show itself. By default, JidePopup is not focusable which means
0038:         * no component in the JidePopup will get focus. For example, if you put a JTextField in JidePopup and the JTextField becomes not editable,
0039:         * this is a result of non-focusable JWindow. So if you want components in JidePopup to be able to receive focus, you can either
0040:         * call setFocusable(true) or you can call {@link #setDefaultFocusComponent(java.awt.Component)} to set a child component
0041:         * as the default focus component.
0042:         */
0043:        public class JidePopup extends JComponent implements  Accessible,
0044:                WindowConstants {
0045:
0046:            /**
0047:             * @see #getUIClassID
0048:             * @see #readObject
0049:             */
0050:            private static final String uiClassID = "JidePopupUI";
0051:
0052:            /**
0053:             * The <code>JRootPane</code> instance that manages the
0054:             * content pane
0055:             * and optional menu bar for this Popup, as well as the
0056:             * glass pane.
0057:             *
0058:             * @see javax.swing.JRootPane
0059:             * @see javax.swing.RootPaneContainer
0060:             */
0061:            private JRootPane rootPane;
0062:
0063:            /**
0064:             * If <code>true</code> then calls to <code>add</code> and <code>setLayout</code>
0065:             * cause an exception to be thrown.
0066:             */
0067:            private boolean rootPaneCheckingEnabled = false;
0068:
0069:            /**
0070:             * Bound property name.
0071:             */
0072:            public final static String CONTENT_PANE_PROPERTY = "contentPane";
0073:
0074:            /**
0075:             * Bound property name.
0076:             */
0077:            public final static String MENU_BAR_PROPERTY = "JMenuBar";
0078:
0079:            /**
0080:             * Bound property name.
0081:             */
0082:            public final static String LAYERED_PANE_PROPERTY = "layeredPane";
0083:
0084:            /**
0085:             * Bound property name.
0086:             */
0087:            public final static String ROOT_PANE_PROPERTY = "rootPane";
0088:
0089:            /**
0090:             * Bound property name.
0091:             */
0092:            public final static String GLASS_PANE_PROPERTY = "glassPane";
0093:
0094:            /**
0095:             * Bound property name.
0096:             */
0097:            public final static String VISIBLE_PROPERTY = "visible";
0098:
0099:            public final static String TRANSIENT_PROPERTY = "transient";
0100:
0101:            /**
0102:             * Constrained property name indicated that this frame has
0103:             * selected status.
0104:             */
0105:
0106:            /**
0107:             * Constrained property name indicating that the popup is attachable.
0108:             */
0109:            public final static String ATTACHABLE_PROPERTY = "attachable";
0110:
0111:            private boolean _attachable = true;
0112:
0113:            /**
0114:             * Bound property name for gripper.
0115:             */
0116:            public final static String MOVABLE_PROPERTY = "movable";
0117:
0118:            /**
0119:             * If the gripper should be shown. Gripper is something on divider to indicate it can be dragged.
0120:             */
0121:            private boolean _movable = false;
0122:
0123:            /**
0124:             * Bound property name for if the popup is detached.
0125:             */
0126:            public final static String DETACHED_PROPERTY = "detached";
0127:
0128:            protected boolean _detached;
0129:
0130:            protected ResizableWindow _window;
0131:
0132:            private ComponentAdapter _componentListener;
0133:            private WindowAdapter _windowListener;
0134:            private ComponentAdapter _ownerComponentListener;
0135:            private HierarchyListener _hierarchyListener;
0136:
0137:            /**
0138:             * Bound property name for resizable.
0139:             */
0140:            public final static String RESIZABLE_PROPERTY = "resizable";
0141:
0142:            private boolean _resizable = true;
0143:
0144:            //    /**
0145:            //     * Bound property name for movable.
0146:            //     */
0147:            //    public final static String MOVABLE_PROPERTY = "movable";
0148:            //
0149:            //    private boolean _movable;
0150:
0151:            /**
0152:             * Bound property name for owner.
0153:             */
0154:            public final static String OWNER_PROPERTY = "owner";
0155:
0156:            private Component _owner;
0157:
0158:            private Border _popupBorder;
0159:
0160:            private boolean _transient = true;
0161:
0162:            private int _timeout = 0;
0163:            private Timer _timer;
0164:
0165:            private Component _defaultFocusComponent;
0166:
0167:            /**
0168:             * Hides the popup when the owner is moved.
0169:             */
0170:            public static final int DO_NOTHING_ON_MOVED = -1;
0171:
0172:            /**
0173:             * Hides the popup when the owner is moved.
0174:             */
0175:            public static final int HIDE_ON_MOVED = 0;
0176:
0177:            /**
0178:             * Moves the popup along with owner when the owner is moved.
0179:             */
0180:            public static final int MOVE_ON_MOVED = 1;
0181:
0182:            private int _defaultMoveOperation = HIDE_ON_MOVED;
0183:            /**
0184:             * The distance between alert and screen border.
0185:             */
0186:            public int DISTANCE_TO_SCREEN_BORDER = 10;
0187:
0188:            private List<Component> _excludedComponents;
0189:
0190:            private int _gripperLocation = SwingConstants.NORTH;
0191:
0192:            public static final String PROPERTY_GRIPPER_LOCATION = "gripperLocation";
0193:            private ComponentAdapter _popupResizeListener;
0194:
0195:            protected Dimension _previousSize;
0196:            private Component _actualOwner;
0197:            private Point _actualOwnerLocation;
0198:
0199:            /**
0200:             * Creates a Popup.
0201:             */
0202:            public JidePopup() {
0203:                _excludedComponents = new ArrayList<Component>();
0204:                setRootPane(createRootPane());
0205:                setLayout(new BorderLayout());
0206:                setRootPaneCheckingEnabled(true);
0207:                setFocusable(false);
0208:                updateUI();
0209:            }
0210:
0211:            /**
0212:             * Called by the constructor to set up the <code>JRootPane</code>.
0213:             *
0214:             * @return a new <code>JRootPane</code>
0215:             * @see javax.swing.JRootPane
0216:             */
0217:            protected JRootPane createRootPane() {
0218:                return new JRootPane();
0219:            }
0220:
0221:            /**
0222:             * Returns the look-and-feel object that renders this component.
0223:             *
0224:             * @return the <code>PopupUI</code> object that renders
0225:             *         this component
0226:             */
0227:            public PopupUI getUI() {
0228:                return (PopupUI) ui;
0229:            }
0230:
0231:            /**
0232:             * Sets the UI delegate for this <code>Popup</code>.
0233:             *
0234:             * @param ui the UI delegate
0235:             */
0236:            public void setUI(PopupUI ui) {
0237:                boolean checkingEnabled = isRootPaneCheckingEnabled();
0238:                try {
0239:                    setRootPaneCheckingEnabled(false);
0240:                    super .setUI(ui);
0241:                } finally {
0242:                    setRootPaneCheckingEnabled(checkingEnabled);
0243:                }
0244:            }
0245:
0246:            /**
0247:             * Notification from the <code>UIManager</code> that the look and feel
0248:             * has changed.
0249:             * Replaces the current UI object with the latest version from the
0250:             * <code>UIManager</code>.
0251:             *
0252:             * @see javax.swing.JComponent#updateUI
0253:             */
0254:            @Override
0255:            public void updateUI() {
0256:                if (UIDefaultsLookup.get(uiClassID) == null) {
0257:                    LookAndFeelFactory.installJideExtension();
0258:                }
0259:                setUI((PopupUI) UIManager.getUI(this ));
0260:                invalidate();
0261:            }
0262:
0263:            /**
0264:             * Returns the name of the look-and-feel
0265:             * class that renders this component.
0266:             *
0267:             * @return the string "PopupUI"
0268:             * @see javax.swing.JComponent#getUIClassID
0269:             * @see javax.swing.UIDefaults#getUI
0270:             */
0271:            @Override
0272:            public String getUIClassID() {
0273:                return uiClassID;
0274:            }
0275:
0276:            /**
0277:             * Returns whether calls to <code>add</code> and
0278:             * <code>setLayout</code> cause an exception to be thrown.
0279:             *
0280:             * @return <code>true</code> if <code>add</code> and <code>setLayout</code>
0281:             *         are checked
0282:             * @see #addImpl
0283:             * @see #setLayout
0284:             * @see #setRootPaneCheckingEnabled
0285:             */
0286:            protected boolean isRootPaneCheckingEnabled() {
0287:                return rootPaneCheckingEnabled;
0288:            }
0289:
0290:            /**
0291:             * Determines whether calls to <code>add</code> and
0292:             * <code>setLayout</code> cause an exception to be thrown.
0293:             *
0294:             * @param enabled a boolean value, <code>true</code> if checking is to be
0295:             *                enabled, which cause the exceptions to be thrown
0296:             * @see #addImpl
0297:             * @see #setLayout
0298:             * @see #isRootPaneCheckingEnabled
0299:             */
0300:            protected void setRootPaneCheckingEnabled(boolean enabled) {
0301:                rootPaneCheckingEnabled = enabled;
0302:            }
0303:
0304:            /**
0305:             * Ensures that, by default, children cannot be added
0306:             * directly to this component.
0307:             * Instead, children must be added to its content pane.
0308:             * For example:
0309:             * <pre>
0310:             * thisComponent.getContentPane().add(child)
0311:             * </pre>
0312:             * An attempt to add to directly to this component will cause a
0313:             * runtime exception to be thrown.  Subclasses can disable this
0314:             * behavior.
0315:             *
0316:             * @param comp        the <code>Component</code> to be added
0317:             * @param constraints the object containing the constraints, if any
0318:             * @param index       the index
0319:             * @throws Error if called with <code>isRootPaneChecking</code> <code>true</code>
0320:             * @see #setRootPaneCheckingEnabled
0321:             */
0322:            @Override
0323:            protected void addImpl(Component comp, Object constraints, int index) {
0324:                if (isRootPaneCheckingEnabled()) {
0325:                    getContentPane().add(comp, constraints, index);
0326:                } else {
0327:                    super .addImpl(comp, constraints, index);
0328:                }
0329:            }
0330:
0331:            /**
0332:             * Removes the specified component from this container.
0333:             *
0334:             * @param comp the component to be removed
0335:             * @see #add
0336:             */
0337:            @Override
0338:            public void remove(Component comp) {
0339:                int oldCount = getComponentCount();
0340:                super .remove(comp);
0341:                if (oldCount == getComponentCount()) {
0342:                    // Client mistake, but we need to handle it to avoid a
0343:                    // common object leak in client applications.
0344:                    getContentPane().remove(comp);
0345:                }
0346:            }
0347:
0348:            /**
0349:             * Ensures that, by default, the layout of this component cannot be set.
0350:             * Instead, the layout of its content pane should be set.
0351:             * For example:
0352:             * <pre>
0353:             * thisComponent.getContentPane().setLayout(new GridLayout(1,2))
0354:             * </pre>
0355:             * An attempt to set the layout of this component will cause an
0356:             * runtime exception to be thrown.  Subclasses can disable this
0357:             * behavior.
0358:             *
0359:             * @param manager the <code>LayoutManager</code>
0360:             * @throws Error if called with <code>isRootPaneChecking</code> <code>true</code>
0361:             * @see #setRootPaneCheckingEnabled
0362:             */
0363:            @Override
0364:            public void setLayout(LayoutManager manager) {
0365:                if (isRootPaneCheckingEnabled()) {
0366:                    getContentPane().setLayout(manager);
0367:                } else {
0368:                    super .setLayout(manager);
0369:                }
0370:            }
0371:
0372:            //////////////////////////////////////////////////////////////////////////
0373:            /// Property Methods
0374:            //////////////////////////////////////////////////////////////////////////
0375:
0376:            /**
0377:             * Returns the current <code>JMenuBar</code> for this
0378:             * <code>Popup</code>, or <code>null</code>
0379:             * if no menu bar has been set.
0380:             *
0381:             * @return the <code>JMenuBar</code> used by this Popup.
0382:             * @see #setJMenuBar
0383:             */
0384:            public JMenuBar getJMenuBar() {
0385:                return getRootPane().getJMenuBar();
0386:            }
0387:
0388:            /**
0389:             * Sets the <code>menuBar</code> property for this <code>Popup</code>.
0390:             *
0391:             * @param m the <code>JMenuBar</code> to use in this Popup.
0392:             * @see #getJMenuBar
0393:             */
0394:            public void setJMenuBar(JMenuBar m) {
0395:                JMenuBar oldValue = getJMenuBar();
0396:                getRootPane().setJMenuBar(m);
0397:                firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
0398:            }
0399:
0400:            // implements javax.swing.RootPaneContainer
0401:
0402:            /**
0403:             * Returns the content pane for this Popup.
0404:             *
0405:             * @return the content pane
0406:             */
0407:            public Container getContentPane() {
0408:                return getRootPane().getContentPane();
0409:            }
0410:
0411:            /**
0412:             * Sets this <code>Popup</code>'s <code>contentPane</code>
0413:             * property.
0414:             *
0415:             * @param c the content pane for this popup.
0416:             * @throws java.awt.IllegalComponentStateException
0417:             *          (a runtime
0418:             *          exception) if the content pane parameter is <code>null</code>
0419:             * @see javax.swing.RootPaneContainer#getContentPane
0420:             */
0421:            public void setContentPane(Container c) {
0422:                Container oldValue = getContentPane();
0423:                getRootPane().setContentPane(c);
0424:                firePropertyChange(CONTENT_PANE_PROPERTY, oldValue, c);
0425:            }
0426:
0427:            /**
0428:             * Returns the layered pane for this popup.
0429:             *
0430:             * @return a <code>JLayeredPane</code> object
0431:             * @see javax.swing.RootPaneContainer#setLayeredPane
0432:             * @see javax.swing.RootPaneContainer#getLayeredPane
0433:             */
0434:            public JLayeredPane getLayeredPane() {
0435:                return getRootPane().getLayeredPane();
0436:            }
0437:
0438:            /**
0439:             * Sets this <code>Popup</code>'s
0440:             * <code>layeredPane</code> property.
0441:             *
0442:             * @param layered the <code>JLayeredPane</code> for this popup
0443:             * @throws java.awt.IllegalComponentStateException
0444:             *          (a runtime
0445:             *          exception) if the layered pane parameter is <code>null</code>
0446:             * @see javax.swing.RootPaneContainer#setLayeredPane
0447:             */
0448:            public void setLayeredPane(JLayeredPane layered) {
0449:                JLayeredPane oldValue = getLayeredPane();
0450:                getRootPane().setLayeredPane(layered);
0451:                firePropertyChange(LAYERED_PANE_PROPERTY, oldValue, layered);
0452:            }
0453:
0454:            /**
0455:             * Returns the glass pane for this popup.
0456:             *
0457:             * @return the glass pane
0458:             * @see javax.swing.RootPaneContainer#setGlassPane
0459:             */
0460:            public Component getGlassPane() {
0461:                return getRootPane().getGlassPane();
0462:            }
0463:
0464:            /**
0465:             * Sets this <code>Popup</code>'s
0466:             * <code>glassPane</code> property.
0467:             *
0468:             * @param glass the glass pane for this popup
0469:             * @see javax.swing.RootPaneContainer#getGlassPane
0470:             */
0471:            public void setGlassPane(Component glass) {
0472:                Component oldValue = getGlassPane();
0473:                getRootPane().setGlassPane(glass);
0474:                firePropertyChange(GLASS_PANE_PROPERTY, oldValue, glass);
0475:            }
0476:
0477:            /**
0478:             * Returns the <code>rootPane</code> object for this popup.
0479:             *
0480:             * @return the <code>rootPane</code> property
0481:             * @see javax.swing.RootPaneContainer#getRootPane
0482:             */
0483:            @Override
0484:            public JRootPane getRootPane() {
0485:                return rootPane;
0486:            }
0487:
0488:            /**
0489:             * Sets the <code>rootPane</code> property
0490:             * for this <code>Popup</code>.
0491:             * This method is called by the constructor.
0492:             *
0493:             * @param root the new <code>JRootPane</code> object
0494:             */
0495:            protected void setRootPane(JRootPane root) {
0496:                if (rootPane != null) {
0497:                    remove(rootPane);
0498:                }
0499:                JRootPane oldValue = getRootPane();
0500:                rootPane = root;
0501:                if (rootPane != null) {
0502:                    boolean checkingEnabled = isRootPaneCheckingEnabled();
0503:                    try {
0504:                        setRootPaneCheckingEnabled(false);
0505:                        add(rootPane, BorderLayout.CENTER);
0506:                    } finally {
0507:                        setRootPaneCheckingEnabled(checkingEnabled);
0508:                    }
0509:                }
0510:                firePropertyChange(ROOT_PANE_PROPERTY, oldValue, root);
0511:            }
0512:
0513:            /**
0514:             * Makes the component visible or invisible.
0515:             * Overrides <code>Component.setVisible</code>.
0516:             *
0517:             * @param visible true to make the component visible; false to
0518:             *                make it invisible
0519:             */
0520:            @Override
0521:            public void setVisible(boolean visible) {
0522:                boolean old = isVisible();
0523:                if (visible != old) {
0524:                    super .setVisible(visible);
0525:                    firePropertyChange(VISIBLE_PROPERTY, old, visible);
0526:                }
0527:            }
0528:
0529:            /**
0530:             * Gets the <code>AccessibleContext</code> associated with this
0531:             * <code>Popup</code>.
0532:             * For popups, the <code>AccessibleContext</code>
0533:             * takes the form of an
0534:             * <code>AccessiblePopup</code> object.
0535:             * A new <code>AccessiblePopup</code> instance is created if necessary.
0536:             *
0537:             * @return an <code>AccessiblePopup</code> that serves as the
0538:             *         <code>AccessibleContext</code> of this
0539:             *         <code>Popup</code>
0540:             * @see com.jidesoft.popup.JidePopup.AccessiblePopup
0541:             */
0542:            @Override
0543:            public AccessibleContext getAccessibleContext() {
0544:                if (accessibleContext == null) {
0545:                    accessibleContext = new AccessiblePopup();
0546:                }
0547:                return accessibleContext;
0548:            }
0549:
0550:            /**
0551:             * This class implements accessibility support for the
0552:             * <code>Popup</code> class.  It provides an implementation of the
0553:             * Java Accessibility API appropriate to popup user-interface
0554:             * elements.
0555:             */
0556:            protected class AccessiblePopup extends AccessibleJComponent
0557:                    implements  AccessibleValue {
0558:
0559:                /**
0560:                 * Get the accessible name of this object.
0561:                 *
0562:                 * @return the localized name of the object -- can be <code>null</code> if this
0563:                 *         object does not have a name
0564:                 * @see #setAccessibleName
0565:                 */
0566:                @Override
0567:                public String getAccessibleName() {
0568:                    if (accessibleName != null) {
0569:                        return accessibleName;
0570:                    } else {
0571:                        return getName();
0572:                    }
0573:                }
0574:
0575:                /**
0576:                 * Get the role of this object.
0577:                 *
0578:                 * @return an instance of AccessibleRole describing the role of the
0579:                 *         object
0580:                 * @see javax.accessibility.AccessibleRole
0581:                 */
0582:                @Override
0583:                public AccessibleRole getAccessibleRole() {
0584:                    return AccessibleRole.SWING_COMPONENT; // use a generic one since there is no specific one to choose
0585:                }
0586:
0587:                /**
0588:                 * Gets the AccessibleValue associated with this object.  In the
0589:                 * implementation of the Java Accessibility API for this class,
0590:                 * returns this object, which is responsible for implementing the
0591:                 * <code>AccessibleValue</code> interface on behalf of itself.
0592:                 *
0593:                 * @return this object
0594:                 */
0595:                @Override
0596:                public AccessibleValue getAccessibleValue() {
0597:                    return this ;
0598:                }
0599:
0600:                //
0601:                // AccessibleValue methods
0602:                //
0603:
0604:                /**
0605:                 * Get the value of this object as a Number.
0606:                 *
0607:                 * @return value of the object -- can be <code>null</code> if this object does not
0608:                 *         have a value
0609:                 */
0610:                public Number getCurrentAccessibleValue() {
0611:                    if (isVisible()) {
0612:                        return 1;
0613:                    } else {
0614:                        return 0;
0615:                    }
0616:                }
0617:
0618:                /**
0619:                 * Set the value of this object as a Number.
0620:                 *
0621:                 * @return <code>true</code> if the value was set
0622:                 */
0623:                public boolean setCurrentAccessibleValue(Number n) {
0624:                    if (n instanceof  Integer) {
0625:                        if (n.intValue() == 0)
0626:                            setVisible(true);
0627:                        else
0628:                            setVisible(false);
0629:                        return true;
0630:                    } else {
0631:                        return false;
0632:                    }
0633:                }
0634:
0635:                /**
0636:                 * Get the minimum value of this object as a Number.
0637:                 *
0638:                 * @return Minimum value of the object; <code>null</code> if this object does not
0639:                 *         have a minimum value
0640:                 */
0641:                public Number getMinimumAccessibleValue() {
0642:                    return Integer.MIN_VALUE;
0643:                }
0644:
0645:                /**
0646:                 * Get the maximum value of this object as a Number.
0647:                 *
0648:                 * @return Maximum value of the object; <code>null</code> if this object does not
0649:                 *         have a maximum value
0650:                 */
0651:                public Number getMaximumAccessibleValue() {
0652:                    return Integer.MAX_VALUE;
0653:                }
0654:            }
0655:
0656:            /**
0657:             * Shows the popup. By default, it will show right below the owner.
0658:             */
0659:            public void showPopup() {
0660:                //David: To account for a popup within a popup, let the caller specify an owner
0661:                //  different from the RootPaneContainer(Applet) or ContentContainer.
0662:                //          showPopup(new Insets(0, 0, 0, 0));
0663:                showPopup(new Insets(0, 0, 0, 0), null);
0664:            }
0665:
0666:            /**
0667:             * Shows the popup. By default, it will show right below the owner after considering the insets.
0668:             *
0669:             * @param owner the popup window's owner; if unspecified, it will default to the
0670:             *              RootPaneContainer(Applet) or ContentContainer
0671:             */
0672:            public void showPopup(Component owner) {
0673:                showPopup(new Insets(0, 0, 0, 0), owner);
0674:            }
0675:
0676:            /**
0677:             * Shows the popup. By default, it will show right below the owner after considering the insets.
0678:             *
0679:             * @param insets the popup's insets
0680:             *               RootPaneContainer(Applet) or ContentContainer
0681:             */
0682:            public void showPopup(Insets insets) {
0683:                showPopup(insets, null);
0684:            }
0685:
0686:            protected Insets _insets = null;
0687:
0688:            /**
0689:             * Shows the popup. By default, it will show right below the owner after considering the insets. Please note, if the owner
0690:             * is not displayed (isShowing returns false), the popup will not be displayed either.
0691:             *
0692:             * @param insets the popup's insets
0693:             * @param owner  the popup window's owner; if unspecified, it will default to the
0694:             *               RootPaneContainer(Applet) or ContentContainer
0695:             */
0696:            public void showPopup(Insets insets, Component owner) {
0697:                _insets = insets;
0698:                Component actualOwner = (owner != null) ? owner : getOwner();
0699:                if (actualOwner != null && actualOwner.isShowing()) {
0700:                    Point point = actualOwner.getLocationOnScreen();
0701:                    internalShowPopup(point.x, point.y, actualOwner);
0702:                } else {
0703:                    showPopup(SwingConstants.CENTER);
0704:                }
0705:            }
0706:
0707:            /**
0708:             * Calculates the popup location.
0709:             *
0710:             * @param point owner is top-left coordinate relative to screen.
0711:             * @param size  the size of the popup window.
0712:             * @param owner the owner
0713:             * @return new popup location. By default, it will return the coordinate of the bottom-left corner of owner.
0714:             */
0715:            protected Point getPopupLocation(Point point, Dimension size,
0716:                    Component owner) {
0717:                Component actualOwner = (owner != null) ? owner : getOwner();
0718:                Dimension ownerSize = actualOwner != null ? actualOwner
0719:                        .getSize() : new Dimension(0, 0);
0720:                Dimension screenSize = PortingUtils.getScreenSize(owner);
0721:
0722:                if (size.width == 0) {
0723:                    size = this .getPreferredSize();
0724:                }
0725:
0726:                Point p = new Point(point.x + _insets.left, point.y
0727:                        + ownerSize.height - _insets.bottom);
0728:                int left = p.x + size.width;
0729:                int bottom = p.y + size.height;
0730:
0731:                if (left > screenSize.width) {
0732:                    p.x -= left - screenSize.width; // move left so that the whole popup can fit in
0733:                }
0734:
0735:                if (bottom > screenSize.height) {
0736:                    p.y = point.y + _insets.top - size.height; // flip to upward
0737:                    if (isResizable()) {
0738:                        setupResizeCorner(Resizable.UPPER_RIGHT);
0739:                    }
0740:                } else {
0741:                    if (isResizable()) {
0742:                        setupResizeCorner(Resizable.LOWER_RIGHT);
0743:                    }
0744:                }
0745:                return p;
0746:            }
0747:
0748:            /**
0749:             * Setup Resizable's ResizeCorner.
0750:             *
0751:             * @param corner the corner.
0752:             */
0753:            public void setupResizeCorner(int corner) {
0754:                switch (corner) {
0755:                case Resizable.UPPER_RIGHT:
0756:                    _window.getResizable().setResizableCorners(
0757:                            Resizable.UPPER_RIGHT);
0758:                    JideSwingUtilities.setRecursively(this ,
0759:                            new JideSwingUtilities.Handler() {
0760:                                public boolean condition(Component c) {
0761:                                    return c instanceof  JideScrollPane;
0762:                                }
0763:
0764:                                public void action(Component c) {
0765:                                    Resizable.ResizeCorner corner = new Resizable.ResizeCorner(
0766:                                            Resizable.UPPER_RIGHT);
0767:                                    corner.addMouseListener(_window
0768:                                            .getResizable()
0769:                                            .getMouseInputAdapter());
0770:                                    corner.addMouseMotionListener(_window
0771:                                            .getResizable()
0772:                                            .getMouseInputAdapter());
0773:                                    ((JideScrollPane) c)
0774:                                            .setScrollBarCorner(
0775:                                                    JideScrollPane.VERTICAL_TOP,
0776:                                                    corner);
0777:                                    ((JideScrollPane) c).setScrollBarCorner(
0778:                                            JideScrollPane.VERTICAL_BOTTOM,
0779:                                            null);
0780:                                }
0781:
0782:                                public void postAction(Component c) {
0783:
0784:                                }
0785:                            });
0786:                    break;
0787:                case Resizable.LOWER_RIGHT:
0788:                    _window.getResizable().setResizableCorners(
0789:                            Resizable.LOWER_RIGHT);
0790:                    JideSwingUtilities.setRecursively(this ,
0791:                            new JideSwingUtilities.Handler() {
0792:                                public boolean condition(Component c) {
0793:                                    return c instanceof  JideScrollPane;
0794:                                }
0795:
0796:                                public void action(Component c) {
0797:                                    Resizable.ResizeCorner corner = new Resizable.ResizeCorner(
0798:                                            Resizable.LOWER_RIGHT);
0799:                                    corner.addMouseListener(_window
0800:                                            .getResizable()
0801:                                            .getMouseInputAdapter());
0802:                                    corner.addMouseMotionListener(_window
0803:                                            .getResizable()
0804:                                            .getMouseInputAdapter());
0805:                                    ((JideScrollPane) c).setScrollBarCorner(
0806:                                            JideScrollPane.VERTICAL_BOTTOM,
0807:                                            corner);
0808:                                    ((JideScrollPane) c).setScrollBarCorner(
0809:                                            JideScrollPane.VERTICAL_TOP, null);
0810:                                }
0811:
0812:                                public void postAction(Component c) {
0813:                                }
0814:                            });
0815:                    break;
0816:                default:
0817:                    _window.getResizable().setResizableCorners(corner);
0818:                    break;
0819:                }
0820:            }
0821:
0822:            public static Component getTopLevelAncestor(Component component) {
0823:                if (component == null) {
0824:                    return null;
0825:                }
0826:
0827:                for (Component p = component; p != null; p = p.getParent()) {
0828:                    if (p instanceof  Window || p instanceof  Applet) {
0829:                        return p;
0830:                    }
0831:                }
0832:                return null;
0833:            }
0834:
0835:            /**
0836:             * Shows the popup at the specified location relative to the screen. The valid locations are:
0837:             * <ul>
0838:             * <li>{@link SwingConstants#CENTER}
0839:             * <li>{@link SwingConstants#SOUTH}
0840:             * <li>{@link SwingConstants#NORTH}
0841:             * <li>{@link SwingConstants#WEST}
0842:             * <li>{@link SwingConstants#EAST}
0843:             * <li>{@link SwingConstants#NORTH_EAST}
0844:             * <li>{@link SwingConstants#NORTH_WEST}
0845:             * <li>{@link SwingConstants#SOUTH_EAST}
0846:             * <li>{@link SwingConstants#SOUTH_WEST}
0847:             * </ul>
0848:             * The actual location will be based on the main screen bounds. Say if the location is SwingConstants.SOUTH_EAST,
0849:             * the popup will appear at the south west corner of main screen with 10 pixels to the border. The 10 pixel is the
0850:             * default value. You can change it by setting {@link #DISTANCE_TO_SCREEN_BORDER}.
0851:             *
0852:             * @param location the new location.
0853:             */
0854:            public void showPopup(int location) {
0855:                showPopup(location, null);
0856:            }
0857:
0858:            /**
0859:             * Shows the popup at the specified location relative to the owner. The valid locations are:
0860:             * <ul>
0861:             * <li>{@link SwingConstants#CENTER}
0862:             * <li>{@link SwingConstants#SOUTH}
0863:             * <li>{@link SwingConstants#NORTH}
0864:             * <li>{@link SwingConstants#WEST}
0865:             * <li>{@link SwingConstants#EAST}
0866:             * <li>{@link SwingConstants#NORTH_EAST}
0867:             * <li>{@link SwingConstants#NORTH_WEST}
0868:             * <li>{@link SwingConstants#SOUTH_EAST}
0869:             * <li>{@link SwingConstants#SOUTH_WEST}
0870:             * </ul>
0871:             * The actual location will be based on the owner's bounds. Say if the location is SwingConstants.SOUTH_EAST,
0872:             * the popup will appear at the south west corner of owner with 10 pixels to the border. The 10 pixel is the
0873:             * default value. You can change it by setting {@link #DISTANCE_TO_SCREEN_BORDER}.
0874:             *
0875:             * @param location the new location
0876:             * @param owner    the popup window's owner; if unspecified, it will default to the
0877:             *                 RootPaneContainer(Applet) or ContentContainer
0878:             */
0879:            public void showPopup(int location, Component owner) {
0880:                setDetached(true);
0881:                Rectangle screenDim = getDisplayScreenBounds(owner);
0882:                // Get the bounds of the splash window
0883:                Dimension size = getPreferredSize();
0884:                Point displayLocation = getDisplayStartLocation(screenDim,
0885:                        size, location);
0886:                internalShowPopup(displayLocation.x, displayLocation.y, owner);
0887:            }
0888:
0889:            protected Point getDisplayStartLocation(Rectangle screenDim,
0890:                    Dimension size, int location) {
0891:                switch (location) {
0892:                case SwingConstants.CENTER:
0893:                    return new Point(screenDim.x
0894:                            + (screenDim.width - size.width) / 2, screenDim.y
0895:                            + (screenDim.height - size.height) / 2);
0896:                case SwingConstants.SOUTH:
0897:                    return new Point(screenDim.x
0898:                            + (screenDim.width - size.width) / 2, screenDim.y
0899:                            + screenDim.height - size.height
0900:                            - DISTANCE_TO_SCREEN_BORDER);
0901:                case SwingConstants.NORTH:
0902:                    return new Point(screenDim.x
0903:                            + (screenDim.width - size.width) / 2, screenDim.y
0904:                            + DISTANCE_TO_SCREEN_BORDER);
0905:                case SwingConstants.EAST:
0906:                    return new Point(screenDim.x + screenDim.width - size.width
0907:                            - DISTANCE_TO_SCREEN_BORDER, screenDim.y
0908:                            + (screenDim.height - size.height) / 2);
0909:                case SwingConstants.WEST:
0910:                    return new Point(screenDim.x + DISTANCE_TO_SCREEN_BORDER,
0911:                            screenDim.y + (screenDim.height - size.height) / 2);
0912:                case SwingConstants.SOUTH_WEST:
0913:                    return new Point(screenDim.x + DISTANCE_TO_SCREEN_BORDER,
0914:                            screenDim.y + screenDim.height - size.height
0915:                                    - DISTANCE_TO_SCREEN_BORDER);
0916:                case SwingConstants.NORTH_EAST:
0917:                    return new Point(screenDim.x + screenDim.width - size.width
0918:                            - DISTANCE_TO_SCREEN_BORDER, screenDim.y
0919:                            + DISTANCE_TO_SCREEN_BORDER);
0920:                case SwingConstants.NORTH_WEST:
0921:                    return new Point(screenDim.x + DISTANCE_TO_SCREEN_BORDER,
0922:                            screenDim.y + DISTANCE_TO_SCREEN_BORDER);
0923:                case SwingConstants.SOUTH_EAST:
0924:                default:
0925:                    return new Point(screenDim.x + screenDim.width - size.width
0926:                            - DISTANCE_TO_SCREEN_BORDER, screenDim.y
0927:                            + screenDim.height - size.height
0928:                            - DISTANCE_TO_SCREEN_BORDER);
0929:                }
0930:            }
0931:
0932:            protected Rectangle getDisplayScreenBounds(Component owner) {
0933:                Rectangle screenDim;
0934:                if (owner != null && owner.isShowing()) {
0935:                    screenDim = owner.getBounds();
0936:                    Point p = owner.getLocationOnScreen();
0937:                    screenDim.x = p.x;
0938:                    screenDim.y = p.y;
0939:                } else {
0940:                    screenDim = PortingUtils.getLocalScreenBounds();
0941:                }
0942:                return screenDim;
0943:            }
0944:
0945:            public void packPopup() {
0946:                if (_window == null || !_window.isVisible()) {
0947:                    return;
0948:                }
0949:                _window.pack();
0950:            }
0951:
0952:            //David: To account for a popup within a popup, let the caller specify an owner
0953:            //  different from the RootPaneContainer(Applet) or ContentContainer.
0954:
0955:            protected void internalShowPopup(int x, int y) {
0956:                internalShowPopup(x, y, null);
0957:            }
0958:
0959:            protected void internalShowPopup(int x, int y, Component owner) {
0960:                _actualOwner = owner;
0961:                if (_actualOwner != null) {
0962:                    _actualOwnerLocation = _actualOwner.getLocationOnScreen();
0963:                }
0964:                createWindow(owner, x, y);
0965:                showPopupImmediately();
0966:            }
0967:
0968:            protected void createWindow(Component owner, int x, int y) {
0969:                if (_window == null) {
0970:                    _window = createPopupContainer(owner);
0971:                    installListeners();
0972:                    installBorder();
0973:                }
0974:
0975:                if (_previousSize != null) {
0976:                    _window.setSize(_previousSize);
0977:                    _previousSize = null;
0978:                } else {
0979:                    _window.pack();
0980:                }
0981:
0982:                if (_insets != null) {
0983:                    Point p = getPopupLocation(new Point(x, y), _window
0984:                            .getSize(), owner);
0985:                    x = p.x;
0986:                    y = p.y;
0987:                }
0988:
0989:                _window.setLocation(x, y);
0990:            }
0991:
0992:            /**
0993:             * Shows the popup at the specified x and y coordinates.
0994:             *
0995:             * @param x the x position.
0996:             * @param y the y position.
0997:             */
0998:            public void showPopup(int x, int y) {
0999:                showPopup(x, y, null);
1000:            }
1001:
1002:            /**
1003:             * Shows the popup at the specified x and y coordinates.
1004:             *
1005:             * @param x     the x position.
1006:             * @param y     the y position.
1007:             * @param owner the popup window's owner; if unspecified, it will default to the
1008:             *              RootPaneContainer(Applet) or ContentContainer
1009:             */
1010:            public void showPopup(int x, int y, Component owner) {
1011:                internalShowPopup(x, y, owner);
1012:            }
1013:
1014:            protected ResizableWindow createPopupContainer() {
1015:                return createPopupContainer(null);
1016:            }
1017:
1018:            protected static Frame getFrame(Component c) {
1019:                Component w = c;
1020:
1021:                while (!(w instanceof  Frame) && (w != null)) {
1022:                    w = w.getParent();
1023:                }
1024:                return (Frame) w;
1025:            }
1026:
1027:            protected ResizableWindow createPopupContainer(Component owner) {
1028:                ResizableWindow container;
1029:                Component actualOwner = (owner != null) ? owner : getOwner();
1030:                Component topLevelAncestor = getTopLevelAncestor(actualOwner);
1031:                if (topLevelAncestor instanceof  Frame) {
1032:                    container = new ResizableWindow((Frame) topLevelAncestor);
1033:                } else if (topLevelAncestor instanceof  Window) {
1034:                    container = new ResizableWindow((Window) topLevelAncestor);
1035:                } else {
1036:                    Frame frame = getFrame(actualOwner);
1037:                    container = new ResizableWindow(frame);
1038:                }
1039:                container.getContentPane().add(this );
1040:                return container;
1041:            }
1042:
1043:            protected void installListeners() {
1044:                //David: Adding the MouseEventHandler synchronously causes a strange
1045:                //  initialization sequence if the popup owner is a tree/table editor:
1046:                //
1047:                //  - The editor gets moved to its initial location based on the cell location,
1048:                //    generating a COMPONENT_MOVED ComponentEvent.
1049:                //  - You add the MouseEventHandler, which includes a ComponentEvent listener on
1050:                //    the owner's hierarcy, including the editor.
1051:                //  - ComponentEvent is asynchronous. The ComponentEvent generated from moving
1052:                //    the editor to its initial position was placed on the event queue. So the
1053:                //    ComponentEvent gets handled by the MouseEventHandler's ComponentEvent
1054:                //    listener, even though it happened before the listener was added.
1055:                //
1056:                //  I fixed it by calling addMouseEventHandler asynchronously, guaranteeing that
1057:                //  any previously-generated event it may listen for has been removed from the
1058:                //  event queue before the listener is added.
1059:                //
1060:                //  This causes a couple of minor problems:
1061:                //
1062:                //  - It is possible that hidePopupImmediately can be called synchronously before
1063:                //    the asynchronous call to addMouseEventHandler is executed. This can cause
1064:                //    NPEs because the listener handler methods dereference _window, which is set
1065:                //    to null in hidePopupImmediately. So I added null checks on _window in the
1066:                //    listener handler methods.
1067:                //
1068:                //  - The removeMouseEventHandler method is called from hidePopupImmediately.
1069:                //    That means it could be called before addMouseEventHandler is executed
1070:                //    asynchronously; that would result in the listener not getting removed. So
1071:                //    I changed the removeMouseEventHandler to an asynchronous call, as well.
1072:                //
1073:                //  This issue appeared in the 1.8.3 release because you changed the
1074:                //  COMPONENT_MOVED handler to hide the popup instead of moving it. Since you
1075:                //  made this an option in the 1.8.4 release, all of this asynchronous code is
1076:                //  needed.
1077:                //
1078:                //        addMouseEventHandler()
1079:                SwingUtilities.invokeLater(new Runnable() {
1080:                    public void run() {
1081:                        addMouseEventHandler();
1082:                    }
1083:                });
1084:                _componentListener = new ComponentAdapter() {
1085:                    @Override
1086:                    public void componentHidden(ComponentEvent e) {
1087:                        hidePopup();
1088:                    }
1089:                };
1090:                registerKeyboardAction(new ActionListener() {
1091:                    public void actionPerformed(ActionEvent e) {
1092:                        hidePopupImmediately(true);
1093:                        if (getOwner() != null) {
1094:                            getOwner().requestFocus();
1095:                        }
1096:                    }
1097:                }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
1098:                        JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
1099:                _window.addComponentListener(_componentListener);
1100:                _windowListener = new WindowAdapter() {
1101:                    @Override
1102:                    public void windowClosing(WindowEvent e) {
1103:                        hidePopup();
1104:                    }
1105:                };
1106:                _window.addWindowListener(_windowListener);
1107:
1108:                if (getOwner() != null) {
1109:                    _ownerComponentListener = new ComponentAdapter() {
1110:                        @Override
1111:                        public void componentHidden(ComponentEvent e) {
1112:                            ancestorHidden();
1113:                        }
1114:
1115:                        @Override
1116:                        public void componentMoved(ComponentEvent e) {
1117:                            if (_actualOwnerLocation == null
1118:                                    || _actualOwner == null
1119:                                    || !_actualOwner.getLocationOnScreen()
1120:                                            .equals(_actualOwnerLocation)) {
1121:                                ancestorMoved();
1122:                            }
1123:                        }
1124:                    };
1125:                    getOwner().addComponentListener(_ownerComponentListener);
1126:                    _hierarchyListener = new HierarchyListener() {
1127:                        public void hierarchyChanged(HierarchyEvent e) {
1128:                            ancestorHidden();
1129:                        }
1130:                    };
1131:                    getOwner().addHierarchyListener(_hierarchyListener);
1132:                }
1133:
1134:                _popupResizeListener = new ComponentAdapter() {
1135:                    @Override
1136:                    public void componentResized(ComponentEvent e) {
1137:                        removeComponentListener(_popupResizeListener);
1138:                        contentResized();
1139:                        addComponentListener(_popupResizeListener);
1140:                    }
1141:                };
1142:                addComponentListener(_popupResizeListener);
1143:            }
1144:
1145:            protected void contentResized() {
1146:                // pack is good enough to replace all code above
1147:                _window.pack();
1148:            }
1149:
1150:            protected void installBorder() {
1151:                if (getPopupBorder() != null) {
1152:                    if (isResizable()) {
1153:                        _window.getResizable().setResizableCorners(
1154:                                Resizable.ALL);
1155:                    } else {
1156:                        _window.getResizable().setResizableCorners(
1157:                                Resizable.NONE);
1158:                    }
1159:                    _window.setBorder(getPopupBorder());
1160:                } else {
1161:                    if (isDetached()) {
1162:                        if (isResizable()) {
1163:                            _window.getResizable().setResizableCorners(
1164:                                    Resizable.ALL);
1165:                        } else {
1166:                            _window.getResizable().setResizableCorners(
1167:                                    Resizable.NONE);
1168:                        }
1169:                        _window.setBorder(UIDefaultsLookup
1170:                                .getBorder("Resizable.resizeBorder"));
1171:                    } else {
1172:                        if (isResizable()) {
1173:                            _window.getResizable().setResizableCorners(
1174:                                    Resizable.RIGHT | Resizable.LOWER
1175:                                            | Resizable.LOWER_RIGHT);
1176:                        } else {
1177:                            _window.getResizable().setResizableCorners(
1178:                                    Resizable.NONE);
1179:                        }
1180:                        _window.setBorder(UIDefaultsLookup
1181:                                .getBorder("PopupMenu.border"));
1182:                    }
1183:                }
1184:            }
1185:
1186:            protected void showPopupImmediately() {
1187:                if (_window == null) {
1188:                    return;
1189:                }
1190:
1191:                firePopupMenuWillBecomeVisible();
1192:
1193:                // only when the focus cycle root is true, the component in JidePopup won't request focus automatically.
1194:                if (!isFocusable() && getDefaultFocusComponent() == null) {
1195:                    _window.setFocusableWindowState(false);
1196:                }
1197:
1198:                if (!_window.isVisible()) {
1199:                    _window.pack();
1200:                    _window.setVisible(true);
1201:                    _window.toFront();
1202:                }
1203:
1204:                firePropertyChange("visible", Boolean.FALSE, Boolean.TRUE);
1205:
1206:                if (isFocusable() || getDefaultFocusComponent() != null) {
1207:                    // only allow window to have focus when there is a default focus component.
1208:                    _window.setFocusable(true);
1209:                    if (getDefaultFocusComponent() != null) {
1210:                        Runnable runnable = new Runnable() {
1211:                            public void run() {
1212:                                getDefaultFocusComponent().requestFocus();
1213:                            }
1214:                        };
1215:                        SwingUtilities.invokeLater(runnable);
1216:                    }
1217:                }
1218:
1219:                if (getTimeout() != 0) {
1220:                    startTimeoutTimer();
1221:                }
1222:            }
1223:
1224:            protected void movePopup() {
1225:                if (isPopupVisible()) {
1226:                    if (!isDetached() && _actualOwner != null) {
1227:                        if (_insets != null) {
1228:                            showPopup(_insets, _actualOwner);
1229:                        } else if (_actualOwnerLocation != null) {
1230:                            Point newLocation = _actualOwner
1231:                                    .getLocationOnScreen();
1232:                            Point p = _window.getLocationOnScreen();
1233:                            p.x += newLocation.x - _actualOwnerLocation.x;
1234:                            p.y += newLocation.y - _actualOwnerLocation.y;
1235:                            showPopup(p.x, p.y, _actualOwner);
1236:                        }
1237:                    }
1238:                }
1239:            }
1240:
1241:            private boolean _isDragging = false;
1242:
1243:            /**
1244:             * Mouse location related the frame it drags.
1245:             */
1246:            private double _relativeX, _relativeY;
1247:
1248:            private Point _startPoint;
1249:            private Window _currentWindow;
1250:
1251:            protected void endDragging() {
1252:                _isDragging = false;
1253:                if (_currentWindow instanceof  JWindow
1254:                        && ((JWindow) _currentWindow).getGlassPane() != null) {
1255:                    ((JWindow) _currentWindow).getGlassPane().setVisible(false);
1256:                    ((JWindow) _currentWindow).getGlassPane().setCursor(
1257:                            Cursor.getDefaultCursor());
1258:                } else if (_currentWindow instanceof  JDialog
1259:                        && ((JDialog) _currentWindow).getGlassPane() != null) {
1260:                    ((JDialog) _currentWindow).getGlassPane().setVisible(false);
1261:                    ((JDialog) _currentWindow).getGlassPane().setCursor(
1262:                            Cursor.getDefaultCursor());
1263:                }
1264:                _currentWindow = null;
1265:                _relativeX = 0;
1266:                _relativeY = 0;
1267:            }
1268:
1269:            protected void beginDragging(JComponent f, int mouseX, int mouseY,
1270:                    double relativeX, double relativeY) {
1271:                _relativeX = relativeX;
1272:                _relativeY = relativeY;
1273:
1274:                if (f.getTopLevelAncestor() instanceof  JWindow)
1275:                    _currentWindow = (JWindow) f.getTopLevelAncestor();
1276:                if (f.getTopLevelAncestor() instanceof  JDialog)
1277:                    _currentWindow = (JDialog) f.getTopLevelAncestor();
1278:
1279:                if (_currentWindow instanceof  JWindow
1280:                        && ((JWindow) _currentWindow).getGlassPane() != null) {
1281:                    ((JWindow) _currentWindow).getGlassPane().setVisible(true);
1282:                    ((JWindow) _currentWindow).getGlassPane().setCursor(
1283:                            Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
1284:                } else if (_currentWindow instanceof  JDialog
1285:                        && ((JDialog) _currentWindow).getGlassPane() != null) {
1286:                    ((JDialog) _currentWindow).getGlassPane().setVisible(true);
1287:                    ((JDialog) _currentWindow).getGlassPane().setCursor(
1288:                            Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
1289:                }
1290:
1291:                _isDragging = true;
1292:                if (isDetached() && getOwner() != null) {
1293:                    _startPoint = getOwner().getLocationOnScreen();
1294:                    _startPoint.y += getOwner().getHeight();
1295:                } else {
1296:                    _startPoint = _currentWindow.getLocationOnScreen();
1297:                }
1298:            }
1299:
1300:            protected boolean isDragging() {
1301:                return _isDragging;
1302:            }
1303:
1304:            static void convertPointToScreen(Point p, Component c,
1305:                    boolean startInFloat) {
1306:                int x, y;
1307:
1308:                do {
1309:                    if (c instanceof  JComponent) {
1310:                        x = c.getX();
1311:                        y = c.getY();
1312:                    } else if (c instanceof  java.applet.Applet
1313:                            || (startInFloat ? c instanceof  Window
1314:                                    : c instanceof  JFrame)) {
1315:                        try {
1316:                            Point pp = c.getLocationOnScreen();
1317:                            x = pp.x;
1318:                            y = pp.y;
1319:                        } catch (IllegalComponentStateException icse) {
1320:                            x = c.getX();
1321:                            y = c.getY();
1322:                        }
1323:                    } else {
1324:                        x = c.getX();
1325:                        y = c.getY();
1326:                    }
1327:
1328:                    p.x += x;
1329:                    p.y += y;
1330:
1331:                    if ((startInFloat ? c instanceof  Window
1332:                            : c instanceof  JFrame)
1333:                            || c instanceof  java.applet.Applet)
1334:                        break;
1335:                    c = c.getParent();
1336:                } while (c != null);
1337:            }
1338:
1339:            protected void drag(JComponent f, int newX, int newY,
1340:                    int mouseModifiers) {
1341:                int x = newX - (int) (_currentWindow.getWidth() * _relativeX);
1342:                int y = newY - (int) (_currentWindow.getHeight() * _relativeY);
1343:                Rectangle bounds = new Rectangle(x, y, _currentWindow
1344:                        .getWidth(), _currentWindow.getHeight());
1345:
1346:                Rectangle screenBounds = PortingUtils
1347:                        .getScreenBounds(_currentWindow);
1348:                if (bounds.y + bounds.height > screenBounds.y
1349:                        + screenBounds.height) {
1350:                    bounds.y = screenBounds.y + screenBounds.height
1351:                            - bounds.height;
1352:                }
1353:                if (bounds.y < screenBounds.y) {
1354:                    bounds.y = screenBounds.y;
1355:                }
1356:
1357:                if (isAttachable()
1358:                        && isWithinAroundArea(new Point(x, y), _startPoint)) {
1359:                    _currentWindow.setLocation(_startPoint);
1360:                    setDetached(false);
1361:                } else {
1362:                    _currentWindow.setLocation(x, y);
1363:                    setDetached(true);
1364:                }
1365:            }
1366:
1367:            final int AROUND_SIZE = 10;
1368:
1369:            boolean isWithinAroundArea(Point p, Point newPoint) {
1370:                Rectangle rect = new Rectangle(p.x - AROUND_SIZE, p.y
1371:                        - AROUND_SIZE, p.x + AROUND_SIZE, p.y + AROUND_SIZE);
1372:                return rect.contains(newPoint);
1373:            }
1374:
1375:            static boolean isAncestorOf(Component component, Object ancester) {
1376:                if (component == null) {
1377:                    return false;
1378:                }
1379:
1380:                for (Component p = component; p != null; p = p.getParent()) {
1381:                    if (p == ancester) {
1382:                        return true;
1383:                    }
1384:                }
1385:                return false;
1386:            }
1387:
1388:            //    private AWTEventListener _awtEventListener = new AWTEventListener() {
1389:            //        public void eventDispatched(AWTEvent event) {
1390:            //            if (event instanceof MouseEvent) {
1391:            //                if (event.getID() == MouseEvent.MOUSE_PRESSED) {
1392:            //                    MouseEvent e = (MouseEvent) event;
1393:            //                    Object source = SwingUtilities.getDeepestComponentAt(e.getComponent(), e.getX(), e.getY());
1394:            //                    if (!isAncestorOf((Container) source, JidePopup.this.getTopLevelAncestor())) { // todo: add a flag to not hidepopup in some cases
1395:            //                        hidePopup();
1396:            //                    }
1397:            //                    else {
1398:            //                        Point point = SwingUtilities.convertPoint((Component) e.getSource(), e.getPoint(), JidePopup.this);
1399:            //
1400:            //                        Rectangle startingBounds = JidePopup.this.getTopLevelAncestor().getBounds();
1401:            //                        _relativeX = (double) point.x / startingBounds.width;
1402:            //                        _relativeY = (double) point.y / startingBounds.height;
1403:            //
1404:            //                        Point screenPoint = new Point(e.getX(), e.getY());
1405:            //                        JidePopup.convertPointToScreen(screenPoint, (Component) e.getSource(), true);
1406:            //
1407:            //                        // drag on gripper
1408:            //                        if (source == JidePopup.this.getUI().getGripper()) {
1409:            //                            beginDragging(JidePopup.this, screenPoint.x, screenPoint.y, _relativeX, _relativeY);
1410:            //                            e.consume();
1411:            //                        }
1412:            //                    }
1413:            //                }
1414:            //                else if (event.getID() == MouseEvent.MOUSE_DRAGGED) {
1415:            //                    if (isDragging()) {
1416:            //                        MouseEvent e = (MouseEvent) event;
1417:            //                        Point screenPoint = e.getPoint();
1418:            //                        convertPointToScreen(screenPoint, ((Component) e.getSource()), true);
1419:            //                        drag(null, screenPoint.x, screenPoint.y, e.getModifiersEx());
1420:            //                        e.consume();
1421:            //                    }
1422:            //                }
1423:            //                else if (event.getID() == MouseEvent.MOUSE_RELEASED) {
1424:            //                    if (isDragging()) {
1425:            //                        MouseEvent e = (MouseEvent) event;
1426:            //                        endDragging();
1427:            //                        e.consume();
1428:            //                    }
1429:            //                }
1430:            //                else if (event.getID() == MouseEvent.MOUSE_ENTERED) {
1431:            //                    if (_window.isAncestorOf(((Component) event.getSource())) && getTimeout() != 0) {
1432:            //                        stopTimeoutTimer();
1433:            //                    }
1434:            //                }
1435:            //                else if (event.getID() == MouseEvent.MOUSE_EXITED) {
1436:            //                    if (_window.isAncestorOf(((Component) event.getSource())) && getTimeout() != 0) {
1437:            //                        startTimeoutTimer();
1438:            //                    }
1439:            //                }
1440:            //            }
1441:            //            else if (event instanceof WindowEvent) {
1442:            //                WindowEvent e = (WindowEvent) event;
1443:            //                if (e.getSource() != JidePopup.this.getTopLevelAncestor() && isAncestorOf(getOwner(), e.getWindow())) {
1444:            //                    if (e.getID() == WindowEvent.WINDOW_CLOSING || e.getID() == WindowEvent.WINDOW_ICONIFIED) {
1445:            //                        hidePopup();
1446:            //                    }
1447:            //                }
1448:            //            }
1449:            //            else if (event instanceof ComponentEvent) {
1450:            //                ComponentEvent e = (ComponentEvent) event;
1451:            //                if (e.getID() == ComponentEvent.COMPONENT_HIDDEN && isAncestorOf(getOwner(), e.getSource())) {
1452:            //                    hidePopup();
1453:            //                }
1454:            //                else if (e.getID() == ComponentEvent.COMPONENT_MOVED && isAncestorOf(getOwner(), e.getSource())) {
1455:            //                    movePopup();
1456:            //                }
1457:            //            }
1458:            //        }
1459:            //    };
1460:
1461:            private AWTEventListener _awtEventListener = new AWTEventListener() {
1462:                public void eventDispatched(AWTEvent event) {
1463:                    if ("sun.awt.UngrabEvent"
1464:                            .equals(event.getClass().getName())) {
1465:                        // this is really a hack so that it can detect event when closing the windows in Eclise RCP env.
1466:                        // Popup should be canceled in case of ungrab event
1467:                        hidePopupImmediately(true);
1468:                        return;
1469:                    }
1470:
1471:                    if (event instanceof  MouseEvent) {
1472:                        if (event.getID() == MouseEvent.MOUSE_PRESSED) {
1473:                            handleMousePressed((MouseEvent) event);
1474:                        } else if (event.getID() == MouseEvent.MOUSE_DRAGGED) {
1475:                            handleMouseDragged((MouseEvent) event);
1476:                        } else if (event.getID() == MouseEvent.MOUSE_RELEASED) {
1477:                            handleMouseReleased((MouseEvent) event);
1478:                        } else if (event.getID() == MouseEvent.MOUSE_ENTERED) {
1479:                            handleMouseEntered((MouseEvent) event);
1480:                        } else if (event.getID() == MouseEvent.MOUSE_EXITED) {
1481:                            handleMouseExited((MouseEvent) event);
1482:                        }
1483:                    } else if (event instanceof  WindowEvent) {
1484:                        handleWindowEvent((WindowEvent) event);
1485:                    } else if (event instanceof  ComponentEvent) {
1486:                        handleComponentEvent((ComponentEvent) event);
1487:                    }
1488:                }
1489:            };
1490:
1491:            protected void handleMousePressed(MouseEvent e) {
1492:                Object source = SwingUtilities.getDeepestComponentAt(e
1493:                        .getComponent(), e.getX(), e.getY());
1494:                Component component = (Component) source;
1495:                if (!isAncestorOf(component, getTopLevelAncestor())) {
1496:                    if (isExcludedComponent(component)) {
1497:                        return;
1498:                    }
1499:                    ancestorHidden();
1500:                } else {
1501:                    Point point = SwingUtilities.convertPoint(component, e
1502:                            .getPoint(), this );
1503:
1504:                    Rectangle startingBounds = getTopLevelAncestor()
1505:                            .getBounds();
1506:                    _relativeX = (double) point.x / startingBounds.width;
1507:                    _relativeY = (double) point.y / startingBounds.height;
1508:
1509:                    Point screenPoint = new Point(e.getX(), e.getY());
1510:                    convertPointToScreen(screenPoint, component, true);
1511:
1512:                    // drag on gripper
1513:                    if (source == getUI().getGripper()) {
1514:                        beginDragging(this , screenPoint.x, screenPoint.y,
1515:                                _relativeX, _relativeY);
1516:                        e.consume();
1517:                    }
1518:                }
1519:            }
1520:
1521:            protected void handleMouseReleased(MouseEvent e) {
1522:                if (isDragging()) {
1523:                    endDragging();
1524:                    e.consume();
1525:                }
1526:            }
1527:
1528:            protected void handleMouseDragged(MouseEvent e) {
1529:                if (isDragging()) {
1530:                    Point screenPoint = e.getPoint();
1531:                    convertPointToScreen(screenPoint, ((Component) e
1532:                            .getSource()), true);
1533:                    drag(null, screenPoint.x, screenPoint.y, e.getModifiersEx());
1534:                    e.consume();
1535:                }
1536:            }
1537:
1538:            protected void handleMouseEntered(MouseEvent e) {
1539:                if ((_window != null)
1540:                        && _window.isAncestorOf(((Component) e.getSource()))
1541:                        && getTimeout() != 0) {
1542:                    stopTimeoutTimer();
1543:                }
1544:            }
1545:
1546:            protected void handleMouseExited(MouseEvent e) {
1547:                //        if (_window.isAncestorOf(((Component) e.getSource())) && getTimeout() != 0) {
1548:                if ((_window != null)
1549:                        && _window.isAncestorOf(((Component) e.getSource()))
1550:                        && getTimeout() != 0) {
1551:                    startTimeoutTimer();
1552:                }
1553:            }
1554:
1555:            private static boolean checkedUnpostPopup;
1556:            private static boolean unpostPopup;
1557:
1558:            private static boolean doUnpostPopupOnDeactivation() {
1559:                if (!checkedUnpostPopup) {
1560:                    unpostPopup = (Boolean) java.security.AccessController
1561:                            .doPrivileged(new java.security.PrivilegedAction() {
1562:                                public Object run() {
1563:                                    String pKey = "sun.swing.unpostPopupsOnWindowDeactivation";
1564:                                    String value = System.getProperty(pKey,
1565:                                            "true");
1566:                                    return Boolean.valueOf(value);
1567:                                }
1568:                            });
1569:                    checkedUnpostPopup = true;
1570:                }
1571:                return unpostPopup;
1572:            }
1573:
1574:            protected void handleWindowEvent(WindowEvent e) {
1575:                if (e.getSource() != getTopLevelAncestor()
1576:                        && isAncestorOf(getOwner(), e.getWindow())) { // check if it's embeded in browser
1577:                    if (e.getID() == WindowEvent.WINDOW_CLOSING
1578:                            || e.getID() == WindowEvent.WINDOW_ICONIFIED) {
1579:                        hidePopup(true);
1580:                    }
1581:
1582:                    // The cases for window deactivated are too complex. Let's not consider it for now.
1583:                    // One case the code below didn't consider is an dialog is shown while in another thread, alert is showing and the owner is the frame.
1584:                    // At the end, frame received deactivated event and cause alert to hide immediately.
1585:                    //
1586:                    // 1/2/07: we have to put this code back because combobox's popup not hiding when the window is deactivated.
1587:                    // But I also copied the code from MenuSelectionManager to check doUnpostPopupOnDeactivation. Hopefully that addresses the issue above.
1588:                    else if (isTransient()
1589:                            && e.getID() == WindowEvent.WINDOW_DEACTIVATED
1590:                            && !(e.getWindow() instanceof  EmbeddedFrame)) {
1591:                        // TODO: don't why DEACTIVATED event is fired when popup is showing only if the applet is in browser mode.
1592:                        // so the best solution is to find out why. For now just skip the case if the frame is a EmbeddedFrame.
1593:                        if (doUnpostPopupOnDeactivation()) {
1594:                            if (e.getOppositeWindow() != getTopLevelAncestor()) {
1595:                                hidePopup(true);
1596:                            }
1597:                        }
1598:                    }
1599:                }
1600:            }
1601:
1602:            /**
1603:             * This method will process component event. By default, if popup's ancestor is hidden, we will hide the popup as well
1604:             * if the popup is transient (isTransient returns true). If popup's ancestor is moved, we will either move or hide
1605:             * the popup depending on {@link #getDefaultMoveOperation()} value.
1606:             *
1607:             * @param e the ComponentEvent.
1608:             */
1609:            protected void handleComponentEvent(ComponentEvent e) {
1610:                if (e.getID() == ComponentEvent.COMPONENT_HIDDEN
1611:                        && isAncestorOf(getOwner(), e.getSource())) {
1612:                    ancestorHidden();
1613:                } else if (e.getID() == ComponentEvent.COMPONENT_MOVED
1614:                        && isAncestorOf(getOwner(), e.getSource())) {
1615:                    // this line is for Linux because the jframe moves when combobox is shown inside JidePopup
1616:                    //            System.out.println("_actualOwnerLocation " + _actualOwnerLocation + " _actualOwner " + _actualOwner + " _actualOwner.getLocationOnScreen() " + (_actualOwner != null ? _actualOwner.getLocationOnScreen() : null));
1617:                    if (_actualOwnerLocation == null
1618:                            || _actualOwner == null
1619:                            || !_actualOwner.getLocationOnScreen().equals(
1620:                                    _actualOwnerLocation)) {
1621:                        ancestorMoved();
1622:                    }
1623:                }
1624:            }
1625:
1626:            /**
1627:             * This method will process component hidden event for the popup's ancestor.
1628:             * By default we will hide the popup immediately. You can override this to customize
1629:             * the behavior.
1630:             */
1631:            protected void ancestorHidden() {
1632:                if (isTransient()) {
1633:                    hidePopupImmediately(true);
1634:                }
1635:            }
1636:
1637:            /**
1638:             * This method will process component moved event for the popup's ancestor.
1639:             * By default we will move the popup if getDefaultMoveOperation() is MOVE_ON_MOVED,
1640:             * or hide the popup if getDefaultMoveOperation() is HIDE_ON_MOVED. You can override this to customize
1641:             * the behavior.
1642:             */
1643:            protected void ancestorMoved() {
1644:                if (getDefaultMoveOperation() == MOVE_ON_MOVED) {
1645:                    movePopup();
1646:                } else if (getDefaultMoveOperation() == HIDE_ON_MOVED) {
1647:                    if (isTransient()) {
1648:                        hidePopupImmediately(true);
1649:                    }
1650:                }
1651:            }
1652:
1653:            public void hidePopup() {
1654:                hidePopup(false);
1655:            }
1656:
1657:            public void hidePopup(boolean cancelled) {
1658:                if (_window == null || !_window.isShowing()) { // not showing. It must be closed already
1659:                    return;
1660:                }
1661:                hidePopupImmediately(cancelled);
1662:            }
1663:
1664:            public boolean isPopupVisible() {
1665:                return _window != null;
1666:            }
1667:
1668:            public Rectangle getPopupBounds() {
1669:                return isPopupVisible() ? _window.getBounds() : null;
1670:            }
1671:
1672:            public void hidePopupImmediately(boolean cancelled) {
1673:                if (getOwner() != null) {
1674:                    getOwner().removeHierarchyListener(_hierarchyListener);
1675:                    getOwner().removeComponentListener(_ownerComponentListener);
1676:                }
1677:                if (_window != null) {
1678:                    _window.removeWindowListener(_windowListener);
1679:                    _window.removeComponentListener(_componentListener);
1680:                    _window.getContentPane().remove(this );
1681:                    if (cancelled) {
1682:                        firePopupMenuCanceled(); // will cause hidePopupImmediately called again.
1683:                    }
1684:                    firePopupMenuWillBecomeInvisible();
1685:                }
1686:                if (_popupResizeListener != null) {
1687:                    removeComponentListener(_popupResizeListener);
1688:                    _popupResizeListener = null;
1689:                }
1690:
1691:                if (_window != null) {
1692:                    _previousSize = _window.getSize();
1693:                    _window.setVisible(false);
1694:                    firePropertyChange("visible", Boolean.TRUE, Boolean.FALSE);
1695:                    _window.dispose();
1696:                    _window = null;
1697:                }
1698:                //<syd_0034>
1699:                //David: There are synchronous events which can result in a call to
1700:                //  hidePopupImmediately. Because I made the call to addMouseEventHandler
1701:                //  asynchronous, this can result in a situation where hidePopupImmediately
1702:                //  gets called before addMouseEventHandler is executed. In that situation, the
1703:                //  mouseEventHandler would be added after it was removed, resulting in the
1704:                //  handler hanging around. So I call the removeMouseEventHandler method
1705:                //  asynchronously, as well, to insure that it happens after
1706:                //  addMouseEventHandler.
1707:                //        removeMouseEventHandler();
1708:                SwingUtilities.invokeLater(new Runnable() {
1709:                    public void run() {
1710:                        removeMouseEventHandler();
1711:                    }
1712:                });
1713:                //</syd_0034>
1714:
1715:                // comment out because bug report on http://www.jidesoft.com/forum/viewtopic.php?p=10333#10333.
1716:                if (getOwner() != null && getOwner().isShowing()) {
1717:                    Component owner = getOwner();
1718:                    for (Container p = owner.getParent(); p != null; p = p
1719:                            .getParent()) {
1720:                        if (p instanceof  JPopupMenu)
1721:                            break;
1722:                        if (p instanceof  Window) {
1723:                            if (!((Window) p).isFocused()) {
1724:                                boolean success = owner.requestFocusInWindow();
1725:                                if (!success) {
1726:                                    owner.requestFocus();
1727:                                }
1728:                                break;
1729:                            }
1730:                        }
1731:                    }
1732:                }
1733:
1734:                _actualOwner = null;
1735:                _actualOwnerLocation = null;
1736:            }
1737:
1738:            /**
1739:             * Hides the popup immediately (compare to {@link #hidePopup()} could use animation to hide the popup).
1740:             */
1741:            public void hidePopupImmediately() {
1742:                hidePopupImmediately(false);
1743:            }
1744:
1745:            /**
1746:             * Add an entry to global event queue.
1747:             */
1748:            private void addMouseEventHandler() {
1749:                if (SecurityUtils.isAWTEventListenerDisabled()
1750:                        || "true".equals(SecurityUtils.getProperty(
1751:                                "jide.disableAWTEventListener", "false"))) {
1752:                    return;
1753:                }
1754:
1755:                try {
1756:                    java.security.AccessController
1757:                            .doPrivileged(new java.security.PrivilegedAction() {
1758:                                public Object run() {
1759:                                    Toolkit
1760:                                            .getDefaultToolkit()
1761:                                            .addAWTEventListener(
1762:                                                    _awtEventListener,
1763:                                                    AWTEvent.MOUSE_EVENT_MASK
1764:                                                            | AWTEvent.MOUSE_MOTION_EVENT_MASK
1765:                                                            | AWTEvent.WINDOW_EVENT_MASK
1766:                                                            | AWTEvent.COMPONENT_EVENT_MASK);
1767:                                    return null;
1768:                                }
1769:                            });
1770:                } catch (SecurityException e) {
1771:                    throw new RuntimeException(e);
1772:                }
1773:            }
1774:
1775:            /**
1776:             * Add an entry to global event queue.
1777:             */
1778:            private void removeMouseEventHandler() {
1779:                if (SecurityUtils.isAWTEventListenerDisabled()
1780:                        || "true".equals(SecurityUtils.getProperty(
1781:                                "jide.disableAWTEventListener", "false"))) {
1782:                    return;
1783:                }
1784:
1785:                try {
1786:                    java.security.AccessController
1787:                            .doPrivileged(new java.security.PrivilegedAction() {
1788:                                public Object run() {
1789:                                    Toolkit.getDefaultToolkit()
1790:                                            .removeAWTEventListener(
1791:                                                    _awtEventListener);
1792:                                    return null;
1793:                                }
1794:                            });
1795:                } catch (SecurityException e) {
1796:                    throw new RuntimeException(e);
1797:                }
1798:            }
1799:
1800:            public Component getOwner() {
1801:                return _owner;
1802:            }
1803:
1804:            public void setOwner(Component owner) {
1805:                if (_owner != owner) {
1806:                    Component old = _owner;
1807:                    _owner = owner;
1808:                    firePropertyChange(OWNER_PROPERTY, old, _owner);
1809:                    removeExcludedComponent(old);
1810:                    addExcludedComponent(_owner);
1811:                }
1812:            }
1813:
1814:            /**
1815:             * Checks if the popup is movable. If yes, it will show the gripper
1816:             * so that user can grab it and move the popup. If the popup is attached to its owner,
1817:             * moving it will detach from the owner.
1818:             *
1819:             * @return true if gripper is visible
1820:             */
1821:            public boolean isMovable() {
1822:                return _movable;
1823:            }
1824:
1825:            /**
1826:             * Sets the movable attribute.
1827:             *
1828:             * @param movable true or false.
1829:             */
1830:            public void setMovable(boolean movable) {
1831:                boolean old = _movable;
1832:                if (old != movable) {
1833:                    _movable = movable;
1834:                    firePropertyChange(MOVABLE_PROPERTY, old, _movable);
1835:                }
1836:            }
1837:
1838:            /**
1839:             * Checks if the popup is resizable. By default, resizable option is true.
1840:             * <p/>
1841:             * Depending on the detached/attached mode, the resizing behavior
1842:             * may be different. If a popup is detached to a component, it only
1843:             * allows you to resize from bottom, bottom right and right
1844:             * It obviously doesn't make sense to resize from top and top side
1845:             * is aligned with the attached component.
1846:             * <p/>
1847:             * (Notes: in the future we will allow resize from different corner if the
1848:             * popup is shown above owner due to not enough space on the screen).
1849:             *
1850:             * @return if the popup is resizable.
1851:             */
1852:            public boolean isResizable() {
1853:                return _resizable;
1854:            }
1855:
1856:            /**
1857:             * Sets the resizable option.
1858:             *
1859:             * @param resizable true or false.
1860:             */
1861:            public void setResizable(boolean resizable) {
1862:                if (_resizable != resizable) {
1863:                    boolean old = _resizable;
1864:                    _resizable = resizable;
1865:                    firePropertyChange(RESIZABLE_PROPERTY, old, _resizable);
1866:                }
1867:            }
1868:
1869:            /**
1870:             * Checks if the popup is attachable. By default, attachable option is true.
1871:             *
1872:             * @return if the popup is attachable.
1873:             */
1874:            public boolean isAttachable() {
1875:                return _attachable;
1876:            }
1877:
1878:            /**
1879:             * Sets the attachable option.
1880:             *
1881:             * @param attachable true or false.
1882:             */
1883:            public void setAttachable(boolean attachable) {
1884:                if (_attachable != attachable) {
1885:                    boolean old = _attachable;
1886:                    _attachable = attachable;
1887:                    firePropertyChange(ATTACHABLE_PROPERTY, old, _attachable);
1888:                }
1889:            }
1890:
1891:            /**
1892:             * Checks if the popup is detached.
1893:             * <p/>
1894:             * A popup has detached and attached mode. When a popup is in attached,
1895:             * it will act like it's part of the owner (which can be set using {@link #setOwner(java.awt.Component)}.
1896:             * When owner is moved, the popup will be moved.
1897:             * If the owner is hidden, the popup will hidden.
1898:             * In the other word, it is attached with the owner.
1899:             * In detached mode, popup becomes an indenpendent floating window.
1900:             * It will stay at the same location regardless if owner is moved.
1901:             * It could still be visible when owner is hidden.
1902:             * <p/>
1903:             *
1904:             * @return true if it's detacted. Otherwise false.
1905:             */
1906:            public boolean isDetached() {
1907:                return _detached;
1908:            }
1909:
1910:            /**
1911:             * Changes the popup's detached mode.
1912:             *
1913:             * @param detached true or false.
1914:             */
1915:            public void setDetached(boolean detached) {
1916:                if (_detached != detached) {
1917:                    boolean old = _detached;
1918:                    _detached = detached;
1919:                    firePropertyChange("detacted", old, _detached);
1920:                    if (_window != null) { // todo: check property change
1921:                        if (_detached) {
1922:                            if (getPopupBorder() == null) {
1923:                                _window.setBorder(UIDefaultsLookup
1924:                                        .getBorder("Resizable.resizeBorder"));
1925:                            } else {
1926:                                _window.setBorder(getPopupBorder());
1927:                            }
1928:                            if (isResizable()) {
1929:                                _window.getResizable().setResizableCorners(
1930:                                        Resizable.ALL);
1931:                            } else {
1932:                                _window.getResizable().setResizableCorners(
1933:                                        Resizable.NONE);
1934:                            }
1935:                        } else {
1936:                            if (getPopupBorder() == null) {
1937:                                _window.setBorder(UIDefaultsLookup
1938:                                        .getBorder("PopupMenu.border"));
1939:                            } else {
1940:                                _window.setBorder(getPopupBorder());
1941:                            }
1942:                            if (isResizable()) {
1943:                                _window.getResizable().setResizableCorners(
1944:                                        Resizable.RIGHT | Resizable.LOWER
1945:                                                | Resizable.LOWER_RIGHT);
1946:                            } else {
1947:                                _window.getResizable().setResizableCorners(
1948:                                        Resizable.NONE);
1949:                            }
1950:                        }
1951:                    }
1952:                }
1953:            }
1954:
1955:            /**
1956:             * Gets the popup border set by {@link #setPopupBorder(javax.swing.border.Border)}.
1957:             *
1958:             * @return the border for this popup.
1959:             */
1960:            public Border getPopupBorder() {
1961:                return _popupBorder;
1962:            }
1963:
1964:            /**
1965:             * Sets the border for this popup. Please note a non-empty border is needed if you want the popup to be
1966:             * resizable.
1967:             *
1968:             * @param popupBorder the border for the popup.
1969:             */
1970:            public void setPopupBorder(Border popupBorder) {
1971:                _popupBorder = popupBorder;
1972:            }
1973:
1974:            /**
1975:             * Checks if the popup is transient.
1976:             *
1977:             * @return true if transient.
1978:             * @see #setTransient(boolean)
1979:             */
1980:            public boolean isTransient() {
1981:                return _transient;
1982:            }
1983:
1984:            /**
1985:             * Sets the transient attribute. If a popup is transient, it will hide automatically when mouse is
1986:             * clicked outside the popup. Otherwise, it will stay visible until timeout or hidePopup() is called.
1987:             *
1988:             * @param isTransient true or false.
1989:             */
1990:            public void setTransient(boolean isTransient) {
1991:                boolean old = _transient;
1992:                if (old != isTransient) {
1993:                    _transient = isTransient;
1994:                    firePropertyChange(TRANSIENT_PROPERTY, old, isTransient);
1995:                }
1996:            }
1997:
1998:            /**
1999:             * Gets the time out value, in milliseconds.
2000:             *
2001:             * @return the time out value, in milliseconds.
2002:             */
2003:            public int getTimeout() {
2004:                return _timeout;
2005:            }
2006:
2007:            /**
2008:             * Sets the time out value, in milliseconds. If you don't want the popup hide
2009:             * after the time out, set the value to 0. By default it's 0 meaning it
2010:             * will never time out.
2011:             * <p/>
2012:             * Typically, you call setTimeOut before the popup is visible. But if you do call setTimeOut when popup is
2013:             * already visible (which means the timer is running), we will restart the timer using the new time out value you
2014:             * just set, even the new time out value is the same as the old one. In the other word, this setTimeOut call
2015:             * will always restart the timer if the timer is running.
2016:             *
2017:             * @param timeout new time out value, in milliseconds. 0 if you don't want popup automatically hides.
2018:             */
2019:            public void setTimeout(int timeout) {
2020:                _timeout = timeout;
2021:                if (_timer != null && _timer.isRunning()) {
2022:                    startTimeoutTimer(); // this call will restart the timer.
2023:                }
2024:            }
2025:
2026:            private void stopTimeoutTimer() {
2027:                if (_timer != null) {
2028:                    _timer.stop();
2029:                    _timer = null;
2030:                    //            System.out.println("stop");
2031:                }
2032:            }
2033:
2034:            private void startTimeoutTimer() {
2035:                stopTimeoutTimer();
2036:                _timer = new Timer(getTimeout(), new ActionListener() {
2037:                    public void actionPerformed(ActionEvent e) {
2038:                        hidePopup();
2039:                    }
2040:                });
2041:                _timer.setRepeats(false);
2042:                _timer.start();
2043:                //        System.out.println("start");
2044:            }
2045:
2046:            /**
2047:             * Gets the default focus component.
2048:             *
2049:             * @return the default focus component.
2050:             */
2051:            public Component getDefaultFocusComponent() {
2052:                return _defaultFocusComponent;
2053:            }
2054:
2055:            /**
2056:             * Sets the default focus component. Default focus component should be a child component on this popup. It will
2057:             * get focus when popup is shown. By setting a non-null component as default focus component, the JWindow that contains the JidePopup will be
2058:             * set focusable. Otherwise the JWindow will be non-focusable.
2059:             *
2060:             * @param defaultFocusComponent the default focus component.
2061:             */
2062:            public void setDefaultFocusComponent(Component defaultFocusComponent) {
2063:                _defaultFocusComponent = defaultFocusComponent;
2064:            }
2065:
2066:            /**
2067:             * Adds a <code>PopupMenu</code> listener which will listen to notification
2068:             * messages from the popup portion of the combo box.
2069:             * <p/>
2070:             * For all standard look and feels shipped with Java 2, the popup list
2071:             * portion of combo box is implemented as a <code>JPopupMenu</code>.
2072:             * A custom look and feel may not implement it this way and will
2073:             * therefore not receive the notification.
2074:             *
2075:             * @param l the <code>PopupMenuListener</code> to add
2076:             */
2077:            public void addPopupMenuListener(PopupMenuListener l) {
2078:                listenerList.add(PopupMenuListener.class, l);
2079:            }
2080:
2081:            /**
2082:             * Removes a <code>PopupMenuListener</code>.
2083:             *
2084:             * @param l the <code>PopupMenuListener</code> to remove
2085:             * @see #addPopupMenuListener
2086:             * @since 1.4
2087:             */
2088:            public void removePopupMenuListener(PopupMenuListener l) {
2089:                listenerList.remove(PopupMenuListener.class, l);
2090:            }
2091:
2092:            /**
2093:             * Returns an array of all the <code>PopupMenuListener</code>s added
2094:             * to this JComboBox with addPopupMenuListener().
2095:             *
2096:             * @return all of the <code>PopupMenuListener</code>s added or an empty
2097:             *         array if no listeners have been added
2098:             */
2099:            public PopupMenuListener[] getPopupMenuListeners() {
2100:                return listenerList.getListeners(PopupMenuListener.class);
2101:            }
2102:
2103:            /**
2104:             * Notifies <code>PopupMenuListener</code>s that the popup portion of the
2105:             * combo box will become visible.
2106:             * <p/>
2107:             * This method is public but should not be called by anything other than
2108:             * the UI delegate.
2109:             *
2110:             * @see #addPopupMenuListener
2111:             */
2112:            public void firePopupMenuWillBecomeVisible() {
2113:                Object[] listeners = listenerList.getListenerList();
2114:                PopupMenuEvent e = null;
2115:                for (int i = listeners.length - 2; i >= 0; i -= 2) {
2116:                    if (listeners[i] == PopupMenuListener.class) {
2117:                        if (e == null)
2118:                            e = new PopupMenuEvent(this );
2119:                        ((PopupMenuListener) listeners[i + 1])
2120:                                .popupMenuWillBecomeVisible(e);
2121:                    }
2122:                }
2123:            }
2124:
2125:            /**
2126:             * Notifies <code>PopupMenuListener</code>s that the popup portion of the
2127:             * combo box has become invisible.
2128:             * <p/>
2129:             * This method is public but should not be called by anything other than
2130:             * the UI delegate.
2131:             *
2132:             * @see #addPopupMenuListener
2133:             */
2134:            public void firePopupMenuWillBecomeInvisible() {
2135:                Object[] listeners = listenerList.getListenerList();
2136:                PopupMenuEvent e = null;
2137:                for (int i = listeners.length - 2; i >= 0; i -= 2) {
2138:                    if (listeners[i] == PopupMenuListener.class) {
2139:                        if (e == null)
2140:                            e = new PopupMenuEvent(this );
2141:                        ((PopupMenuListener) listeners[i + 1])
2142:                                .popupMenuWillBecomeInvisible(e);
2143:                    }
2144:                }
2145:            }
2146:
2147:            /**
2148:             * Notifies <code>PopupMenuListener</code>s that the popup portion of the
2149:             * combo box has been canceled.
2150:             * <p/>
2151:             * This method is public but should not be called by anything other than
2152:             * the UI delegate.
2153:             *
2154:             * @see #addPopupMenuListener
2155:             */
2156:            public void firePopupMenuCanceled() {
2157:                Object[] listeners = listenerList.getListenerList();
2158:                PopupMenuEvent e = null;
2159:                for (int i = listeners.length - 2; i >= 0; i -= 2) {
2160:                    if (listeners[i] == PopupMenuListener.class) {
2161:                        if (e == null)
2162:                            e = new PopupMenuEvent(this );
2163:                        ((PopupMenuListener) listeners[i + 1])
2164:                                .popupMenuCanceled(e);
2165:                    }
2166:                }
2167:            }
2168:
2169:            /**
2170:             * Gets the default operation when the owner is moved. The valid values are either {@link #HIDE_ON_MOVED},
2171:             * {@link #MOVE_ON_MOVED} or {@link #DO_NOTHING_ON_MOVED}.
2172:             *
2173:             * @return the default operation when the owner is moved.
2174:             */
2175:            public int getDefaultMoveOperation() {
2176:                return _defaultMoveOperation;
2177:            }
2178:
2179:            /**
2180:             * Sets the default operation when the owner is moved. The valid could be either {@link #HIDE_ON_MOVED},
2181:             * {@link #MOVE_ON_MOVED} or {@link #DO_NOTHING_ON_MOVED}.
2182:             *
2183:             * @param defaultMoveOperation the default operation when the owner is moved.
2184:             */
2185:            public void setDefaultMoveOperation(int defaultMoveOperation) {
2186:                _defaultMoveOperation = defaultMoveOperation;
2187:            }
2188:
2189:            /**
2190:             * Adds a component as excluded component. If a component is an excluded component or descendant of an excluded component, clicking on it will not
2191:             * hide the popup.
2192:             * <p/>
2193:             * For example, AbstractComboBox uses JidePopup to display the popup. If you want to show a JDialog from the popup, you will
2194:             * have to add the dialog as excluded component. See below for an example.
2195:             * <pre><code>
2196:             * JDialog dialog =new JDialog((Frame) JideSwingUtilities.getWindowForComponent(this), true);
2197:             * dialog.add(new JTable(10, 4));
2198:             * dialog.pack();
2199:             * Container ancestorOfClass = SwingUtilities.getAncestorOfClass(JidePopup.class, this); // try to find the JidePopup
2200:             * if(ancestorOfClass instanceof  JidePopup) {
2201:             *     ((JidePopup) ancestorOfClass).addExcludedComponent(dialog);
2202:             * }
2203:             * dialog.setVisible(true);
2204:             * if(ancestorOfClass instanceof  JidePopup) {
2205:             *     ((JidePopup) ancestorOfClass).removeExcludedComponent(dialog);
2206:             * }
2207:             * </code></pre>
2208:             *
2209:             * @param component the component should be excluded.
2210:             */
2211:            public void addExcludedComponent(Component component) {
2212:                if (component != null
2213:                        && !_excludedComponents.contains(component)) {
2214:                    _excludedComponents.add(component);
2215:                }
2216:            }
2217:
2218:            /**
2219:             * Removes a component from the excluded component list. If a component is an excluded component, clicking on it will not
2220:             * hide the popup.
2221:             *
2222:             * @param component the component was excluded before.
2223:             */
2224:            public void removeExcludedComponent(Component component) {
2225:                _excludedComponents.remove(component);
2226:            }
2227:
2228:            /**
2229:             * Checks if a component is an excluded component. If a component is an excluded component, clicking on it will not
2230:             * hide the popup. By default, owner is always the excluded component.
2231:             *
2232:             * @param component a component.
2233:             * @return true if the component is an excluded component.
2234:             */
2235:            public boolean isExcludedComponent(Component component) {
2236:                boolean contain = _excludedComponents.contains(component);
2237:                if (!contain) {
2238:                    for (Component c : _excludedComponents) {
2239:                        if (c instanceof  Container) {
2240:                            if (((Container) c).isAncestorOf(component)) {
2241:                                return true;
2242:                            }
2243:                        }
2244:                    }
2245:                }
2246:                return contain;
2247:            }
2248:
2249:            public int getGripperLocation() {
2250:                return _gripperLocation;
2251:            }
2252:
2253:            /**
2254:             * Sets the gripper location. The valid values are {@link SwingConstants#NORTH},
2255:             * {@link SwingConstants#SOUTH}, {@link SwingConstants#EAST}, and {@link SwingConstants#WEST}.
2256:             *
2257:             * @param gripperLocation the new gripper location.
2258:             */
2259:            public void setGripperLocation(int gripperLocation) {
2260:                int old = _gripperLocation;
2261:                if (old != gripperLocation) {
2262:                    _gripperLocation = gripperLocation;
2263:                    firePropertyChange(PROPERTY_GRIPPER_LOCATION, old,
2264:                            gripperLocation);
2265:                }
2266:            }
2267:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.