- /*
- * @(#)ToolTipManager.java 1.70 04/01/16
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
-
- package javax.swing;
-
- import java.awt.event.*;
- import java.applet.*;
- import java.awt.*;
- import java.io.Serializable;
- import sun.swing.UIAction;
-
- /**
- * Manages all the <code>ToolTips</code> in the system.
- * <p>
- * ToolTipManager contains numerous properties for configuring how long it
- * will take for the tooltips to become visible, and how long till they
- * hide. Consider a component that has a different tooltip based on where
- * the mouse is, such as JTree. When the mouse moves into the JTree and
- * over a region that has a valid tooltip, the tooltip will become
- * visibile after <code>initialDelay</code> milliseconds. After
- * <code>dismissDelay</code> milliseconds the tooltip will be hidden. If
- * the mouse is over a region that has a valid tooltip, and the tooltip
- * is currently visible, when the mouse moves to a region that doesn't have
- * a valid tooltip the tooltip will be hidden. If the mouse then moves back
- * into a region that has a valid tooltip within <code>reshowDelay</code>
- * milliseconds, the tooltip will immediately be shown, otherwise the
- * tooltip will be shown again after <code>initialDelay</code> milliseconds.
- *
- * @see JComponent#createToolTip
- * @version 1.70 01/16/04
- * @author Dave Moore
- * @author Rich Schiavi
- */
- public class ToolTipManager extends MouseAdapter implements MouseMotionListener {
- Timer enterTimer, exitTimer, insideTimer;
- String toolTipText;
- Point preferredLocation;
- JComponent insideComponent;
- MouseEvent mouseEvent;
- boolean showImmediately;
- final static ToolTipManager sharedInstance = new ToolTipManager();
- transient Popup tipWindow;
- /** The Window tip is being displayed in. This will be non-null if
- * the Window tip is in differs from that of insideComponent's Window.
- */
- private Window window;
- JToolTip tip;
-
- private Rectangle popupRect = null;
- private Rectangle popupFrameRect = null;
-
- boolean enabled = true;
- private boolean tipShowing = false;
-
- private KeyStroke postTip,hideTip;
- private Action postTipAction, hideTipAction;
-
- private FocusListener focusChangeListener = null;
- private MouseMotionListener moveBeforeEnterListener = null;
-
- // PENDING(ges)
- protected boolean lightWeightPopupEnabled = true;
- protected boolean heavyWeightPopupEnabled = false;
-
- ToolTipManager() {
- enterTimer = new Timer(750, new insideTimerAction());
- enterTimer.setRepeats(false);
- exitTimer = new Timer(500, new outsideTimerAction());
- exitTimer.setRepeats(false);
- insideTimer = new Timer(4000, new stillInsideTimerAction());
- insideTimer.setRepeats(false);
-
- // create accessibility actions
- postTip = KeyStroke.getKeyStroke(KeyEvent.VK_F1,Event.CTRL_MASK);
- postTipAction = new Actions(Actions.SHOW);
- hideTip = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0);
- hideTipAction = new Actions(Actions.HIDE);
-
- moveBeforeEnterListener = new MoveBeforeEnterListener();
- }
-
- /**
- * Enables or disables the tooltip.
- *
- * @param flag true to enable the tip, false otherwise
- */
- public void setEnabled(boolean flag) {
- enabled = flag;
- if (!flag) {
- hideTipWindow();
- }
- }
-
- /**
- * Returns true if this object is enabled.
- *
- * @return true if this object is enabled, false otherwise
- */
- public boolean isEnabled() {
- return enabled;
- }
-
- /**
- * When displaying the <code>JToolTip</code>, the
- * <code>ToolTipManager</code> chooses to use a lightweight
- * <code>JPanel</code> if it fits. This method allows you to
- * disable this feature. You have to do disable it if your
- * application mixes light weight and heavy weights components.
- *
- * @param aFlag true if a lightweight panel is desired, false otherwise
- *
- */
- public void setLightWeightPopupEnabled(boolean aFlag){
- lightWeightPopupEnabled = aFlag;
- }
-
- /**
- * Returns true if lightweight (all-Java) <code>Tooltips</code>
- * are in use, or false if heavyweight (native peer)
- * <code>Tooltips</code> are being used.
- *
- * @return true if lightweight <code>ToolTips</code> are in use
- */
- public boolean isLightWeightPopupEnabled() {
- return lightWeightPopupEnabled;
- }
-
-
- /**
- * Specifies the initial delay value.
- *
- * @param milliseconds the number of milliseconds to delay
- * (after the cursor has paused) before displaying the
- * tooltip
- * @see #getInitialDelay
- */
- public void setInitialDelay(int milliseconds) {
- enterTimer.setInitialDelay(milliseconds);
- }
-
- /**
- * Returns the initial delay value.
- *
- * @return an integer representing the initial delay value,
- * in milliseconds
- * @see #setInitialDelay
- */
- public int getInitialDelay() {
- return enterTimer.getInitialDelay();
- }
-
- /**
- * Specifies the dismissal delay value.
- *
- * @param milliseconds the number of milliseconds to delay
- * before taking away the tooltip
- * @see #getDismissDelay
- */
- public void setDismissDelay(int milliseconds) {
- insideTimer.setInitialDelay(milliseconds);
- }
-
- /**
- * Returns the dismissal delay value.
- *
- * @return an integer representing the dismissal delay value,
- * in milliseconds
- * @see #setDismissDelay
- */
- public int getDismissDelay() {
- return insideTimer.getInitialDelay();
- }
-
- /**
- * Used to specify the amount of time before the user has to wait
- * <code>initialDelay</code> milliseconds before a tooltip will be
- * shown. That is, if the tooltip is hidden, and the user moves into
- * a region of the same Component that has a valid tooltip within
- * <code>milliseconds</code> milliseconds the tooltip will immediately
- * be shown. Otherwise, if the user moves into a region with a valid
- * tooltip after <code>milliseconds</code> milliseconds, the user
- * will have to wait an additional <code>initialDelay</code>
- * milliseconds before the tooltip is shown again.
- *
- * @param milliseconds time in milliseconds
- * @see #getReshowDelay
- */
- public void setReshowDelay(int milliseconds) {
- exitTimer.setInitialDelay(milliseconds);
- }
-
- /**
- * Returns the reshow delay property.
- *
- * @return reshown delay property
- * @see #setReshowDelay
- */
- public int getReshowDelay() {
- return exitTimer.getInitialDelay();
- }
-
- void showTipWindow() {
- if(insideComponent == null || !insideComponent.isShowing())
- return;
- for (Container p = insideComponent.getParent(); p != null; p = p.getParent()) {
- if (p instanceof JPopupMenu) break;
- if (p instanceof Window) {
- if (!((Window)p).isFocused()) {
- return;
- }
- break;
- }
- }
- if (enabled) {
- Dimension size;
- Point screenLocation = insideComponent.getLocationOnScreen();
- Point location = new Point();
- Rectangle sBounds = insideComponent.getGraphicsConfiguration().
- getBounds();
- boolean leftToRight
- = SwingUtilities.isLeftToRight(insideComponent);
-
- // Just to be paranoid
- hideTipWindow();
-
- tip = insideComponent.createToolTip();
- tip.setTipText(toolTipText);
- size = tip.getPreferredSize();
-
- if(preferredLocation != null) {
- location.x = screenLocation.x + preferredLocation.x;
- location.y = screenLocation.y + preferredLocation.y;
- if (!leftToRight) {
- location.x -= size.width;
- }
- } else {
- location.x = screenLocation.x + mouseEvent.getX();
- location.y = screenLocation.y + mouseEvent.getY() + 20;
- if (!leftToRight) {
- if(location.x - size.width>=0) {
- location.x -= size.width;
- }
- }
-
- }
-
- // we do not adjust x/y when using awt.Window tips
- if (popupRect == null){
- popupRect = new Rectangle();
- }
- popupRect.setBounds(location.x,location.y,
- size.width,size.height);
-
- // Fit as much of the tooltip on screen as possible
- if (location.x < sBounds.x) {
- location.x = sBounds.x;
- }
- else if (location.x - sBounds.x + size.width > sBounds.width) {
- location.x = sBounds.x + Math.max(0, sBounds.width - size.width)
- ;
- }
- if (location.y < sBounds.y) {
- location.y = sBounds.y;
- }
- else if (location.y - sBounds.y + size.height > sBounds.height) {
- location.y = sBounds.y + Math.max(0, sBounds.height - size.height);
- }
-
- PopupFactory popupFactory = PopupFactory.getSharedInstance();
-
- if (lightWeightPopupEnabled) {
- int y = getPopupFitHeight(popupRect, insideComponent);
- int x = getPopupFitWidth(popupRect,insideComponent);
- if (x>0 || y>0) {
- popupFactory.setPopupType(PopupFactory.MEDIUM_WEIGHT_POPUP);
- } else {
- popupFactory.setPopupType(PopupFactory.LIGHT_WEIGHT_POPUP);
- }
- }
- else {
- popupFactory.setPopupType(PopupFactory.MEDIUM_WEIGHT_POPUP);
- }
- tipWindow = popupFactory.getPopup(insideComponent, tip,
- location.x,
- location.y);
- popupFactory.setPopupType(PopupFactory.LIGHT_WEIGHT_POPUP);
-
- tipWindow.show();
-
- Window componentWindow = SwingUtilities.windowForComponent(
- insideComponent);
-
- window = SwingUtilities.windowForComponent(tip);
- if (window != null && window != componentWindow) {
- window.addMouseListener(this);
- }
- else {
- window = null;
- }
-
- insideTimer.start();
- tipShowing = true;
- }
- }
-
- void hideTipWindow() {
- if (tipWindow != null) {
- if (window != null) {
- window.removeMouseListener(this);
- window = null;
- }
- tipWindow.hide();
- tipWindow = null;
- tipShowing = false;
- (tip.getUI()).uninstallUI(tip);
- tip = null;
- insideTimer.stop();
- }
- }
-
- /**
- * Returns a shared <code>ToolTipManager</code> instance.
- *
- * @return a shared <code>ToolTipManager</code> object
- */
- public static ToolTipManager sharedInstance() {
- return sharedInstance;
- }
-
- // add keylistener here to trigger tip for access
- /**
- * Registers a component for tooltip management.
- * <p>
- * This will register key bindings to show and hide the tooltip text
- * only if <code>component</code> has focus bindings. This is done
- * so that components that are not normally focus traversable, such
- * as <code>JLabel</code>, are not made focus traversable as a result
- * of invoking this method.
- *
- * @param component a <code>JComponent</code> object to add
- * @see JComponent#isFocusTraversable
- */
- public void registerComponent(JComponent component) {
- component.removeMouseListener(this);
- component.addMouseListener(this);
- component.removeMouseMotionListener(moveBeforeEnterListener);
- component.addMouseMotionListener(moveBeforeEnterListener);
-
- if (shouldRegisterBindings(component)) {
- // register our accessibility keybindings for this component
- // this will apply globally across L&F
- // Post Tip: Ctrl+F1
- // Unpost Tip: Esc and Ctrl+F1
- InputMap inputMap = component.getInputMap(JComponent.WHEN_FOCUSED);
- ActionMap actionMap = component.getActionMap();
-
- if (inputMap != null && actionMap != null) {
- inputMap.put(postTip, "postTip");
- inputMap.put(hideTip, "hideTip");
- actionMap.put("postTip", postTipAction);
- actionMap.put("hideTip", hideTipAction);
- }
- }
- }
-
- /**
- * Removes a component from tooltip control.
- *
- * @param component a <code>JComponent</code> object to remove
- */
- public void unregisterComponent(JComponent component) {
- component.removeMouseListener(this);
- component.removeMouseMotionListener(moveBeforeEnterListener);
-
- if (shouldRegisterBindings(component)) {
- InputMap inputMap = component.getInputMap(JComponent.WHEN_FOCUSED);
- ActionMap actionMap = component.getActionMap();
-
- if (inputMap != null && actionMap != null) {
- inputMap.remove(postTip);
- inputMap.remove(hideTip);
- actionMap.remove("postTip");
- actionMap.remove("hideTip");
- }
- }
- }
-
- /**
- * Returns whether or not bindings should be registered on the given
- * <code>JComponent</code>. This is implemented to return true if the
- * tool tip manager has a binding in any one of the
- * <code>InputMaps</code> registered under the condition
- * <code>WHEN_FOCUSED</code>.
- * <p>
- * This does not use <code>isFocusTraversable</code> as
- * some components may override <code>isFocusTraversable</code> and
- * base the return value on something other than bindings. For example,
- * <code>JButton</code> bases its return value on its enabled state.
- *
- * @param component the <code>JComponent</code> in question
- */
- private boolean shouldRegisterBindings(JComponent component) {
- InputMap inputMap = component.getInputMap(JComponent.WHEN_FOCUSED,
- false);
- while (inputMap != null && inputMap.size() == 0) {
- inputMap = inputMap.getParent();
- }
- return (inputMap != null);
- }
-
- // implements java.awt.event.MouseListener
- /**
- * Called when the mouse enters the region of a component.
- * This determines whether the tool tip should be shown.
- *
- * @param event the event in question
- */
- public void mouseEntered(MouseEvent event) {
- initiateToolTip(event);
- }
-
- private void initiateToolTip(MouseEvent event) {
- if (event.getSource() == window) {
- return;
- }
- JComponent component = (JComponent)event.getSource();
- component.removeMouseMotionListener(moveBeforeEnterListener);
-
- exitTimer.stop();
-
- Point location = event.getPoint();
- // ensure tooltip shows only in proper place
- if (location.x < 0 ||
- location.x >=component.getWidth() ||
- location.y < 0 ||
- location.y >= component.getHeight()) {
- return;
- }
-
- if (insideComponent != null) {
- enterTimer.stop();
- }
- // A component in an unactive internal frame is sent two
- // mouseEntered events, make sure we don't end up adding
- // ourselves an extra time.
- component.removeMouseMotionListener(this);
- component.addMouseMotionListener(this);
-
- boolean sameComponent = (insideComponent == component);
-
- insideComponent = component;
- if (tipWindow != null){
- mouseEvent = event;
- if (showImmediately) {
- String newToolTipText = component.getToolTipText(event);
- Point newPreferredLocation = component.getToolTipLocation(
- event);
- boolean sameLoc = (preferredLocation != null) ?
- preferredLocation.equals(newPreferredLocation) :
- (newPreferredLocation == null);
-
- if (!sameComponent || !toolTipText.equals(newToolTipText) ||
- !sameLoc) {
- toolTipText = newToolTipText;
- preferredLocation = newPreferredLocation;
- showTipWindow();
- }
- } else {
- enterTimer.start();
- }
- }
- }
-
- // implements java.awt.event.MouseListener
- /**
- * Called when the mouse exits the region of a component.
- * Any tool tip showing should be hidden.
- *
- * @param event the event in question
- */
- public void mouseExited(MouseEvent event) {
- boolean shouldHide = true;
- if (insideComponent == null) {
- // Drag exit
- }
- if (window != null && event.getSource() == window) {
- // if we get an exit and have a heavy window
- // we need to check if it if overlapping the inside component
- Container insideComponentWindow = insideComponent.getTopLevelAncestor();
- Point location = event.getPoint();
- SwingUtilities.convertPointToScreen(location, window);
-
- location.x -= insideComponentWindow.getX();
- location.y -= insideComponentWindow.getY();
-
- location = SwingUtilities.convertPoint(null,location,insideComponent);
- if (location.x >= 0 && location.x < insideComponent.getWidth() &&
- location.y >= 0 && location.y < insideComponent.getHeight()) {
- shouldHide = false;
- } else {
- shouldHide = true;
- }
- } else if(event.getSource() == insideComponent && tipWindow != null) {
- Window win = SwingUtilities.getWindowAncestor(insideComponent);
- if (win != null) { // insideComponent may have been hidden (e.g. in a menu)
- Point location = SwingUtilities.convertPoint(insideComponent,
- event.getPoint(),
- win);
- Rectangle bounds = insideComponent.getTopLevelAncestor().getBounds();
- location.x += bounds.x;
- location.y += bounds.y;
-
- Point loc = new Point(0, 0);
- SwingUtilities.convertPointToScreen(loc, tip);
- bounds.x = loc.x;
- bounds.y = loc.y;
- bounds.width = tip.getWidth();
- bounds.height = tip.getHeight();
-
- if (location.x >= bounds.x && location.x < (bounds.x + bounds.width) &&
- location.y >= bounds.y && location.y < (bounds.y + bounds.height)) {
- shouldHide = false;
- } else {
- shouldHide = true;
- }
- }
- }
-
- if (shouldHide) {
- enterTimer.stop();
- if (insideComponent != null) {
- insideComponent.removeMouseMotionListener(this);
- }
- insideComponent = null;
- toolTipText = null;
- mouseEvent = null;
- hideTipWindow();
- exitTimer.restart();
- }
- }
-
- // implements java.awt.event.MouseListener
- /**
- * Called when the mouse is pressed.
- * Any tool tip showing should be hidden.
- *
- * @param event the event in question
- */
- public void mousePressed(MouseEvent event) {
- hideTipWindow();
- enterTimer.stop();
- showImmediately = false;
- insideComponent = null;
- mouseEvent = null;
- }
-
- // implements java.awt.event.MouseMotionListener
- /**
- * Called when the mouse is pressed and dragged.
- * Does nothing.
- *
- * @param event the event in question
- */
- public void mouseDragged(MouseEvent event) {
- }
-
- // implements java.awt.event.MouseMotionListener
- /**
- * Called when the mouse is moved.
- * Determines whether the tool tip should be displayed.
- *
- * @param event the event in question
- */
- public void mouseMoved(MouseEvent event) {
- if (tipShowing) {
- checkForTipChange(event);
- }
- else if (showImmediately) {
- JComponent component = (JComponent)event.getSource();
- toolTipText = component.getToolTipText(event);
- if (toolTipText != null) {
- preferredLocation = component.getToolTipLocation(event);
- mouseEvent = event;
- insideComponent = component;
- exitTimer.stop();
- showTipWindow();
- }
- }
- else {
- // Lazily lookup the values from within insideTimerAction
- insideComponent = (JComponent)event.getSource();
- mouseEvent = event;
- toolTipText = null;
- enterTimer.restart();
- }
- }
-
- /**
- * Checks to see if the tooltip needs to be changed in response to
- * the MouseMoved event <code>event</code>.
- */
- private void checkForTipChange(MouseEvent event) {
- JComponent component = (JComponent)event.getSource();
- String newText = component.getToolTipText(event);
- Point newPreferredLocation = component.getToolTipLocation(event);
-
- if (newText != null || newPreferredLocation != null) {
- mouseEvent = event;
- if (((newText != null && newText.equals(toolTipText)) || newText == null) &&
- ((newPreferredLocation != null && newPreferredLocation.equals(preferredLocation))
- || newPreferredLocation == null)) {
- if (tipWindow != null) {
- insideTimer.restart();
- } else {
- enterTimer.restart();
- }
- } else {
- toolTipText = newText;
- preferredLocation = newPreferredLocation;
- if (showImmediately) {
- hideTipWindow();
- showTipWindow();
- exitTimer.stop();
- } else {
- enterTimer.restart();
- }
- }
- } else {
- toolTipText = null;
- preferredLocation = null;
- mouseEvent = null;
- insideComponent = null;
- hideTipWindow();
- enterTimer.stop();
- exitTimer.restart();
- }
- }
-
- protected class insideTimerAction implements ActionListener {
- public void actionPerformed(ActionEvent e) {
- if(insideComponent != null && insideComponent.isShowing()) {
- // Lazy lookup
- if (toolTipText == null && mouseEvent != null) {
- toolTipText = insideComponent.getToolTipText(mouseEvent);
- preferredLocation = insideComponent.getToolTipLocation(
- mouseEvent);
- }
- if(toolTipText != null) {
- showImmediately = true;
- showTipWindow();
- }
- else {
- insideComponent = null;
- toolTipText = null;
- preferredLocation = null;
- mouseEvent = null;
- hideTipWindow();
- }
- }
- }
- }
-
- protected class outsideTimerAction implements ActionListener {
- public void actionPerformed(ActionEvent e) {
- showImmediately = false;
- }
- }
-
- protected class stillInsideTimerAction implements ActionListener {
- public void actionPerformed(ActionEvent e) {
- hideTipWindow();
- enterTimer.stop();
- showImmediately = false;
- insideComponent = null;
- mouseEvent = null;
- }
- }
-
- /* This listener is registered when the tooltip is first registered
- * on a component in order to catch the situation where the tooltip
- * was turned on while the mouse was already within the bounds of
- * the component. This way, the tooltip will be initiated on a
- * mouse-entered or mouse-moved, whichever occurs first. Once the
- * tooltip has been initiated, we can remove this listener and rely
- * solely on mouse-entered to initiate the tooltip.
- */
- private class MoveBeforeEnterListener extends MouseMotionAdapter {
- public void mouseMoved(MouseEvent e) {
- initiateToolTip(e);
- }
- }
-
- static Frame frameForComponent(Component component) {
- while (!(component instanceof Frame)) {
- component = component.getParent();
- }
- return (Frame)component;
- }
-
- private FocusListener createFocusChangeListener(){
- return new FocusAdapter(){
- public void focusLost(FocusEvent evt){
- hideTipWindow();
- insideComponent = null;
- JComponent c = (JComponent)evt.getSource();
- c.removeFocusListener(focusChangeListener);
- }
- };
- }
-
- // Returns: 0 no adjust
- // -1 can't fit
- // >0 adjust value by amount returned
- private int getPopupFitWidth(Rectangle popupRectInScreen, Component invoker){
- if (invoker != null){
- Container parent;
- for (parent = invoker.getParent(); parent != null; parent = parent.getParent()){
- // fix internal frame size bug: 4139087 - 4159012
- if(parent instanceof JFrame || parent instanceof JDialog ||
- parent instanceof JWindow) { // no check for awt.Frame since we use Heavy tips
- return getWidthAdjust(parent.getBounds(),popupRectInScreen);
- } else if (parent instanceof JApplet || parent instanceof JInternalFrame) {
- if (popupFrameRect == null){
- popupFrameRect = new Rectangle();
- }
- Point p = parent.getLocationOnScreen();
- popupFrameRect.setBounds(p.x,p.y,
- parent.getBounds().width,
- parent.getBounds().height);
- return getWidthAdjust(popupFrameRect,popupRectInScreen);
- }
- }
- }
- return 0;
- }
-
- // Returns: 0 no adjust
- // >0 adjust by value return
- private int getPopupFitHeight(Rectangle popupRectInScreen, Component invoker){
- if (invoker != null){
- Container parent;
- for (parent = invoker.getParent(); parent != null; parent = parent.getParent()){
- if(parent instanceof JFrame || parent instanceof JDialog ||
- parent instanceof JWindow) {
- return getHeightAdjust(parent.getBounds(),popupRectInScreen);
- } else if (parent instanceof JApplet || parent instanceof JInternalFrame) {
- if (popupFrameRect == null){
- popupFrameRect = new Rectangle();
- }
- Point p = parent.getLocationOnScreen();
- popupFrameRect.setBounds(p.x,p.y,
- parent.getBounds().width,
- parent.getBounds().height);
- return getHeightAdjust(popupFrameRect,popupRectInScreen);
- }
- }
- }
- return 0;
- }
-
- private int getHeightAdjust(Rectangle a, Rectangle b){
- if (b.y >= a.y && (b.y + b.height) <= (a.y + a.height))
- return 0;
- else
- return (((b.y + b.height) - (a.y + a.height)) + 5);
- }
-
- // Return the number of pixels over the edge we are extending.
- // If we are over the edge the ToolTipManager can adjust.
- // REMIND: what if the Tooltip is just too big to fit at all - we currently will just clip
- private int getWidthAdjust(Rectangle a, Rectangle b){
- // System.out.println("width b.x/b.width: " + b.x + "/" + b.width +
- // "a.x/a.width: " + a.x + "/" + a.width);
- if (b.x >= a.x && (b.x + b.width) <= (a.x + a.width)){
- return 0;
- }
- else {
- return (((b.x + b.width) - (a.x +a.width)) + 5);
- }
- }
-
-
- //
- // Actions
- //
- private void show(JComponent source) {
- if (tipWindow != null) { // showing we unshow
- hideTipWindow();
- insideComponent = null;
- }
- else {
- hideTipWindow(); // be safe
- enterTimer.stop();
- exitTimer.stop();
- insideTimer.stop();
- insideComponent = source;
- if (insideComponent != null){
- toolTipText = insideComponent.getToolTipText();
- preferredLocation = new Point(10,insideComponent.getHeight()+
- 10); // manual set
- showTipWindow();
- // put a focuschange listener on to bring the tip down
- if (focusChangeListener == null){
- focusChangeListener = createFocusChangeListener();
- }
- insideComponent.addFocusListener(focusChangeListener);
- }
- }
- }
-
- private void hide(JComponent source) {
- hideTipWindow();
- source.removeFocusListener(focusChangeListener);
- preferredLocation = null;
- insideComponent = null;
- }
-
-
- private static class Actions extends UIAction {
- private static String SHOW = "SHOW";
- private static String HIDE = "HIDE";
-
- Actions(String key) {
- super(key);
- }
-
- public void actionPerformed(ActionEvent e) {
- String key = getName();
- JComponent source = (JComponent)e.getSource();
- if (key == SHOW) {
- ToolTipManager.sharedInstance().show(source);
- }
- else if (key == HIDE) {
- ToolTipManager.sharedInstance().hide(source);
- }
- }
-
- public boolean isEnabled(Object sender) {
- if (getName() == SHOW) {
- return true;
- }
- return ToolTipManager.sharedInstance().tipShowing;
- }
- }
- }