< prev index next >

src/java.desktop/share/classes/javax/swing/ToolTipManager.java

Print this page




  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 
  27 package javax.swing;
  28 
  29 import java.awt.event.*;
  30 import java.awt.*;
  31 import java.util.Objects;
  32 
  33 /**
  34  * Manages all the <code>ToolTips</code> in the system.
  35  * <p>
  36  * ToolTipManager contains numerous properties for configuring how long it
  37  * will take for the tooltips to become visible, and how long till they
  38  * hide. Consider a component that has a different tooltip based on where
  39  * the mouse is, such as JTree. When the mouse moves into the JTree and
  40  * over a region that has a valid tooltip, the tooltip will become
  41  * visible after <code>initialDelay</code> milliseconds. After
  42  * <code>dismissDelay</code> milliseconds the tooltip will be hidden. If
  43  * the mouse is over a region that has a valid tooltip, and the tooltip
  44  * is currently visible, when the mouse moves to a region that doesn't have
  45  * a valid tooltip the tooltip will be hidden. If the mouse then moves back
  46  * into a region that has a valid tooltip within <code>reshowDelay</code>
  47  * milliseconds, the tooltip will immediately be shown, otherwise the
  48  * tooltip will be shown again after <code>initialDelay</code> milliseconds.
  49  *
  50  * @see JComponent#createToolTip
  51  * @author Dave Moore
  52  * @author Rich Schiavi
  53  * @since 1.2
  54  */
  55 public class ToolTipManager extends MouseAdapter implements MouseMotionListener  {
  56     Timer enterTimer, exitTimer, insideTimer;
  57     String toolTipText;
  58     Point  preferredLocation;
  59     JComponent insideComponent;
  60     MouseEvent mouseEvent;
  61     boolean showImmediately;
  62     private static final Object TOOL_TIP_MANAGER_KEY = new Object();
  63     transient Popup tipWindow;
  64     /** The Window tip is being displayed in. This will be non-null if
  65      * the Window tip is in differs from that of insideComponent's Window.
  66      */
  67     private Window window;
  68     JToolTip tip;


 109      *
 110      * @param flag  true to enable the tip, false otherwise
 111      */
 112     public void setEnabled(boolean flag) {
 113         enabled = flag;
 114         if (!flag) {
 115             hideTipWindow();
 116         }
 117     }
 118 
 119     /**
 120      * Returns true if this object is enabled.
 121      *
 122      * @return true if this object is enabled, false otherwise
 123      */
 124     public boolean isEnabled() {
 125         return enabled;
 126     }
 127 
 128     /**
 129      * When displaying the <code>JToolTip</code>, the
 130      * <code>ToolTipManager</code> chooses to use a lightweight
 131      * <code>JPanel</code> if it fits. This method allows you to
 132      * disable this feature. You have to do disable it if your
 133      * application mixes light weight and heavy weights components.
 134      *
 135      * @param aFlag true if a lightweight panel is desired, false otherwise
 136      *
 137      */
 138     public void setLightWeightPopupEnabled(boolean aFlag){
 139         lightWeightPopupEnabled = aFlag;
 140     }
 141 
 142     /**
 143      * Returns true if lightweight (all-Java) <code>Tooltips</code>
 144      * are in use, or false if heavyweight (native peer)
 145      * <code>Tooltips</code> are being used.
 146      *
 147      * @return true if lightweight <code>ToolTips</code> are in use
 148      */
 149     public boolean isLightWeightPopupEnabled() {
 150         return lightWeightPopupEnabled;
 151     }
 152 
 153 
 154     /**
 155      * Specifies the initial delay value.
 156      *
 157      * @param milliseconds  the number of milliseconds to delay
 158      *        (after the cursor has paused) before displaying the
 159      *        tooltip
 160      * @see #getInitialDelay
 161      */
 162     public void setInitialDelay(int milliseconds) {
 163         enterTimer.setInitialDelay(milliseconds);
 164     }
 165 
 166     /**
 167      * Returns the initial delay value.


 181      *        before taking away the tooltip
 182      * @see #getDismissDelay
 183      */
 184     public void setDismissDelay(int milliseconds) {
 185         insideTimer.setInitialDelay(milliseconds);
 186     }
 187 
 188     /**
 189      * Returns the dismissal delay value.
 190      *
 191      * @return an integer representing the dismissal delay value,
 192      *          in milliseconds
 193      * @see #setDismissDelay
 194      */
 195     public int getDismissDelay() {
 196         return insideTimer.getInitialDelay();
 197     }
 198 
 199     /**
 200      * Used to specify the amount of time before the user has to wait
 201      * <code>initialDelay</code> milliseconds before a tooltip will be
 202      * shown. That is, if the tooltip is hidden, and the user moves into
 203      * a region of the same Component that has a valid tooltip within
 204      * <code>milliseconds</code> milliseconds the tooltip will immediately
 205      * be shown. Otherwise, if the user moves into a region with a valid
 206      * tooltip after <code>milliseconds</code> milliseconds, the user
 207      * will have to wait an additional <code>initialDelay</code>
 208      * milliseconds before the tooltip is shown again.
 209      *
 210      * @param milliseconds time in milliseconds
 211      * @see #getReshowDelay
 212      */
 213     public void setReshowDelay(int milliseconds) {
 214         exitTimer.setInitialDelay(milliseconds);
 215     }
 216 
 217     /**
 218      * Returns the reshow delay property.
 219      *
 220      * @return reshown delay property
 221      * @see #setReshowDelay
 222      */
 223     public int getReshowDelay() {
 224         return exitTimer.getInitialDelay();
 225     }
 226 
 227     // Returns GraphicsConfiguration instance that toFind belongs to or null


 367             insideTimer.start();
 368         tipShowing = true;
 369         }
 370     }
 371 
 372     void hideTipWindow() {
 373         if (tipWindow != null) {
 374             if (window != null) {
 375                 window.removeMouseListener(this);
 376                 window = null;
 377             }
 378             tipWindow.hide();
 379             tipWindow = null;
 380             tipShowing = false;
 381             tip = null;
 382             insideTimer.stop();
 383         }
 384     }
 385 
 386     /**
 387      * Returns a shared <code>ToolTipManager</code> instance.
 388      *
 389      * @return a shared <code>ToolTipManager</code> object
 390      */
 391     public static ToolTipManager sharedInstance() {
 392         Object value = SwingUtilities.appContextGet(TOOL_TIP_MANAGER_KEY);
 393         if (value instanceof ToolTipManager) {
 394             return (ToolTipManager) value;
 395         }
 396         ToolTipManager manager = new ToolTipManager();
 397         SwingUtilities.appContextPut(TOOL_TIP_MANAGER_KEY, manager);
 398         return manager;
 399     }
 400 
 401     // add keylistener here to trigger tip for access
 402     /**
 403      * Registers a component for tooltip management.
 404      * <p>
 405      * This will register key bindings to show and hide the tooltip text
 406      * only if <code>component</code> has focus bindings. This is done
 407      * so that components that are not normally focus traversable, such
 408      * as <code>JLabel</code>, are not made focus traversable as a result
 409      * of invoking this method.
 410      *
 411      * @param component  a <code>JComponent</code> object to add
 412      * @see JComponent#isFocusTraversable
 413      */
 414     public void registerComponent(JComponent component) {
 415         component.removeMouseListener(this);
 416         component.addMouseListener(this);
 417         component.removeMouseMotionListener(moveBeforeEnterListener);
 418         component.addMouseMotionListener(moveBeforeEnterListener);
 419         component.removeKeyListener(accessibilityKeyListener);
 420         component.addKeyListener(accessibilityKeyListener);
 421     }
 422 
 423     /**
 424      * Removes a component from tooltip control.
 425      *
 426      * @param component  a <code>JComponent</code> object to remove
 427      */
 428     public void unregisterComponent(JComponent component) {
 429         component.removeMouseListener(this);
 430         component.removeMouseMotionListener(moveBeforeEnterListener);
 431         component.removeKeyListener(accessibilityKeyListener);
 432     }
 433 
 434     // implements java.awt.event.MouseListener
 435     /**
 436      *  Called when the mouse enters the region of a component.
 437      *  This determines whether the tool tip should be shown.
 438      *
 439      *  @param event  the event in question
 440      */
 441     public void mouseEntered(MouseEvent event) {
 442         initiateToolTip(event);
 443     }
 444 
 445     private void initiateToolTip(MouseEvent event) {
 446         if (event.getSource() == window) {


 606             toolTipText = component.getToolTipText(event);
 607             if (toolTipText != null) {
 608                 preferredLocation = component.getToolTipLocation(event);
 609                 mouseEvent = event;
 610                 insideComponent = component;
 611                 exitTimer.stop();
 612                 showTipWindow();
 613             }
 614         }
 615         else {
 616             // Lazily lookup the values from within insideTimerAction
 617             insideComponent = (JComponent)event.getSource();
 618             mouseEvent = event;
 619             toolTipText = null;
 620             enterTimer.restart();
 621         }
 622     }
 623 
 624     /**
 625      * Checks to see if the tooltip needs to be changed in response to
 626      * the MouseMoved event <code>event</code>.
 627      */
 628     private void checkForTipChange(MouseEvent event) {
 629         JComponent component = (JComponent)event.getSource();
 630         String newText = component.getToolTipText(event);
 631         Point  newPreferredLocation = component.getToolTipLocation(event);
 632 
 633         if (newText != null || newPreferredLocation != null) {
 634             mouseEvent = event;
 635             if (((newText != null && newText.equals(toolTipText)) || newText == null) &&
 636                 ((newPreferredLocation != null && newPreferredLocation.equals(preferredLocation))
 637                  || newPreferredLocation == null)) {
 638                 if (tipWindow != null) {
 639                     insideTimer.restart();
 640                 } else {
 641                     enterTimer.restart();
 642                 }
 643             } else {
 644                 toolTipText = newText;
 645                 preferredLocation = newPreferredLocation;
 646                 if (showImmediately) {




  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 
  27 package javax.swing;
  28 
  29 import java.awt.event.*;
  30 import java.awt.*;
  31 import java.util.Objects;
  32 
  33 /**
  34  * Manages all the {@code ToolTips} in the system.
  35  * <p>
  36  * ToolTipManager contains numerous properties for configuring how long it
  37  * will take for the tooltips to become visible, and how long till they
  38  * hide. Consider a component that has a different tooltip based on where
  39  * the mouse is, such as JTree. When the mouse moves into the JTree and
  40  * over a region that has a valid tooltip, the tooltip will become
  41  * visible after {@code initialDelay} milliseconds. After
  42  * {@code dismissDelay} milliseconds the tooltip will be hidden. If
  43  * the mouse is over a region that has a valid tooltip, and the tooltip
  44  * is currently visible, when the mouse moves to a region that doesn't have
  45  * a valid tooltip the tooltip will be hidden. If the mouse then moves back
  46  * into a region that has a valid tooltip within {@code reshowDelay}
  47  * milliseconds, the tooltip will immediately be shown, otherwise the
  48  * tooltip will be shown again after {@code initialDelay} milliseconds.
  49  *
  50  * @see JComponent#createToolTip
  51  * @author Dave Moore
  52  * @author Rich Schiavi
  53  * @since 1.2
  54  */
  55 public class ToolTipManager extends MouseAdapter implements MouseMotionListener  {
  56     Timer enterTimer, exitTimer, insideTimer;
  57     String toolTipText;
  58     Point  preferredLocation;
  59     JComponent insideComponent;
  60     MouseEvent mouseEvent;
  61     boolean showImmediately;
  62     private static final Object TOOL_TIP_MANAGER_KEY = new Object();
  63     transient Popup tipWindow;
  64     /** The Window tip is being displayed in. This will be non-null if
  65      * the Window tip is in differs from that of insideComponent's Window.
  66      */
  67     private Window window;
  68     JToolTip tip;


 109      *
 110      * @param flag  true to enable the tip, false otherwise
 111      */
 112     public void setEnabled(boolean flag) {
 113         enabled = flag;
 114         if (!flag) {
 115             hideTipWindow();
 116         }
 117     }
 118 
 119     /**
 120      * Returns true if this object is enabled.
 121      *
 122      * @return true if this object is enabled, false otherwise
 123      */
 124     public boolean isEnabled() {
 125         return enabled;
 126     }
 127 
 128     /**
 129      * When displaying the {@code JToolTip}, the
 130      * {@code ToolTipManager} chooses to use a lightweight
 131      * {@code JPanel} if it fits. This method allows you to
 132      * disable this feature. You have to do disable it if your
 133      * application mixes light weight and heavy weights components.
 134      *
 135      * @param aFlag true if a lightweight panel is desired, false otherwise
 136      *
 137      */
 138     public void setLightWeightPopupEnabled(boolean aFlag){
 139         lightWeightPopupEnabled = aFlag;
 140     }
 141 
 142     /**
 143      * Returns true if lightweight (all-Java) {@code Tooltips}
 144      * are in use, or false if heavyweight (native peer)
 145      * {@code Tooltips} are being used.
 146      *
 147      * @return true if lightweight {@code ToolTips} are in use
 148      */
 149     public boolean isLightWeightPopupEnabled() {
 150         return lightWeightPopupEnabled;
 151     }
 152 
 153 
 154     /**
 155      * Specifies the initial delay value.
 156      *
 157      * @param milliseconds  the number of milliseconds to delay
 158      *        (after the cursor has paused) before displaying the
 159      *        tooltip
 160      * @see #getInitialDelay
 161      */
 162     public void setInitialDelay(int milliseconds) {
 163         enterTimer.setInitialDelay(milliseconds);
 164     }
 165 
 166     /**
 167      * Returns the initial delay value.


 181      *        before taking away the tooltip
 182      * @see #getDismissDelay
 183      */
 184     public void setDismissDelay(int milliseconds) {
 185         insideTimer.setInitialDelay(milliseconds);
 186     }
 187 
 188     /**
 189      * Returns the dismissal delay value.
 190      *
 191      * @return an integer representing the dismissal delay value,
 192      *          in milliseconds
 193      * @see #setDismissDelay
 194      */
 195     public int getDismissDelay() {
 196         return insideTimer.getInitialDelay();
 197     }
 198 
 199     /**
 200      * Used to specify the amount of time before the user has to wait
 201      * {@code initialDelay} milliseconds before a tooltip will be
 202      * shown. That is, if the tooltip is hidden, and the user moves into
 203      * a region of the same Component that has a valid tooltip within
 204      * {@code milliseconds} milliseconds the tooltip will immediately
 205      * be shown. Otherwise, if the user moves into a region with a valid
 206      * tooltip after {@code milliseconds} milliseconds, the user
 207      * will have to wait an additional {@code initialDelay}
 208      * milliseconds before the tooltip is shown again.
 209      *
 210      * @param milliseconds time in milliseconds
 211      * @see #getReshowDelay
 212      */
 213     public void setReshowDelay(int milliseconds) {
 214         exitTimer.setInitialDelay(milliseconds);
 215     }
 216 
 217     /**
 218      * Returns the reshow delay property.
 219      *
 220      * @return reshown delay property
 221      * @see #setReshowDelay
 222      */
 223     public int getReshowDelay() {
 224         return exitTimer.getInitialDelay();
 225     }
 226 
 227     // Returns GraphicsConfiguration instance that toFind belongs to or null


 367             insideTimer.start();
 368         tipShowing = true;
 369         }
 370     }
 371 
 372     void hideTipWindow() {
 373         if (tipWindow != null) {
 374             if (window != null) {
 375                 window.removeMouseListener(this);
 376                 window = null;
 377             }
 378             tipWindow.hide();
 379             tipWindow = null;
 380             tipShowing = false;
 381             tip = null;
 382             insideTimer.stop();
 383         }
 384     }
 385 
 386     /**
 387      * Returns a shared {@code ToolTipManager} instance.
 388      *
 389      * @return a shared {@code ToolTipManager} object
 390      */
 391     public static ToolTipManager sharedInstance() {
 392         Object value = SwingUtilities.appContextGet(TOOL_TIP_MANAGER_KEY);
 393         if (value instanceof ToolTipManager) {
 394             return (ToolTipManager) value;
 395         }
 396         ToolTipManager manager = new ToolTipManager();
 397         SwingUtilities.appContextPut(TOOL_TIP_MANAGER_KEY, manager);
 398         return manager;
 399     }
 400 
 401     // add keylistener here to trigger tip for access
 402     /**
 403      * Registers a component for tooltip management.
 404      * <p>
 405      * This will register key bindings to show and hide the tooltip text
 406      * only if {@code component} has focus bindings. This is done
 407      * so that components that are not normally focus traversable, such
 408      * as {@code JLabel}, are not made focus traversable as a result
 409      * of invoking this method.
 410      *
 411      * @param component  a {@code JComponent} object to add
 412      * @see JComponent#isFocusTraversable
 413      */
 414     public void registerComponent(JComponent component) {
 415         component.removeMouseListener(this);
 416         component.addMouseListener(this);
 417         component.removeMouseMotionListener(moveBeforeEnterListener);
 418         component.addMouseMotionListener(moveBeforeEnterListener);
 419         component.removeKeyListener(accessibilityKeyListener);
 420         component.addKeyListener(accessibilityKeyListener);
 421     }
 422 
 423     /**
 424      * Removes a component from tooltip control.
 425      *
 426      * @param component  a {@code JComponent} object to remove
 427      */
 428     public void unregisterComponent(JComponent component) {
 429         component.removeMouseListener(this);
 430         component.removeMouseMotionListener(moveBeforeEnterListener);
 431         component.removeKeyListener(accessibilityKeyListener);
 432     }
 433 
 434     // implements java.awt.event.MouseListener
 435     /**
 436      *  Called when the mouse enters the region of a component.
 437      *  This determines whether the tool tip should be shown.
 438      *
 439      *  @param event  the event in question
 440      */
 441     public void mouseEntered(MouseEvent event) {
 442         initiateToolTip(event);
 443     }
 444 
 445     private void initiateToolTip(MouseEvent event) {
 446         if (event.getSource() == window) {


 606             toolTipText = component.getToolTipText(event);
 607             if (toolTipText != null) {
 608                 preferredLocation = component.getToolTipLocation(event);
 609                 mouseEvent = event;
 610                 insideComponent = component;
 611                 exitTimer.stop();
 612                 showTipWindow();
 613             }
 614         }
 615         else {
 616             // Lazily lookup the values from within insideTimerAction
 617             insideComponent = (JComponent)event.getSource();
 618             mouseEvent = event;
 619             toolTipText = null;
 620             enterTimer.restart();
 621         }
 622     }
 623 
 624     /**
 625      * Checks to see if the tooltip needs to be changed in response to
 626      * the MouseMoved event {@code event}.
 627      */
 628     private void checkForTipChange(MouseEvent event) {
 629         JComponent component = (JComponent)event.getSource();
 630         String newText = component.getToolTipText(event);
 631         Point  newPreferredLocation = component.getToolTipLocation(event);
 632 
 633         if (newText != null || newPreferredLocation != null) {
 634             mouseEvent = event;
 635             if (((newText != null && newText.equals(toolTipText)) || newText == null) &&
 636                 ((newPreferredLocation != null && newPreferredLocation.equals(preferredLocation))
 637                  || newPreferredLocation == null)) {
 638                 if (tipWindow != null) {
 639                     insideTimer.restart();
 640                 } else {
 641                     enterTimer.restart();
 642                 }
 643             } else {
 644                 toolTipText = newText;
 645                 preferredLocation = newPreferredLocation;
 646                 if (showImmediately) {


< prev index next >