/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package javax.swing;
import java.awt.event.*;
import java.awt.*;
/**
* 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
* visible 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
* @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;
private static final
Object TOOL_TIP_MANAGER_KEY = new
Object();
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
FocusListener focusChangeListener = null;
private
MouseMotionListener moveBeforeEnterListener = null;
private
KeyListener accessibilityKeyListener = null;
private
KeyStroke postTip;
private
KeyStroke hideTip;
// 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);
moveBeforeEnterListener = new
MoveBeforeEnterListener();
accessibilityKeyListener = new
AccessibilityKeyListener();
postTip =
KeyStroke.
getKeyStroke(
KeyEvent.
VK_F1,
InputEvent.
CTRL_MASK);
hideTip =
KeyStroke.
getKeyStroke(
KeyEvent.
VK_ESCAPE, 0);
}
/**
* 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();
}
// Returns GraphicsConfiguration instance that toFind belongs to or null
// if drawing point is set to a point beyond visible screen area (e.g.
// Point(20000, 20000))
private
GraphicsConfiguration getDrawingGC(
Point toFind) {
GraphicsEnvironment env =
GraphicsEnvironment.
getLocalGraphicsEnvironment();
GraphicsDevice devices[] =
env.
getScreenDevices();
for (
GraphicsDevice device :
devices) {
GraphicsConfiguration configs[] =
device.
getConfigurations();
for (
GraphicsConfiguration config :
configs) {
Rectangle rect =
config.
getBounds();
if (
rect.
contains(
toFind)) {
return
config;
}
}
}
return null;
}
void
showTipWindow() {
if(
insideComponent == null || !
insideComponent.
isShowing())
return;
String mode =
UIManager.
getString("ToolTipManager.enableToolTipMode");
if ("activeApplication".
equals(
mode)) {
KeyboardFocusManager kfm =
KeyboardFocusManager.
getCurrentKeyboardFocusManager();
if (
kfm.
getFocusedWindow() == null) {
return;
}
}
if (
enabled) {
Dimension size;
Point screenLocation =
insideComponent.
getLocationOnScreen();
Point location;
Point toFind;
if (
preferredLocation != null) {
toFind = new
Point(
screenLocation.
x +
preferredLocation.
x,
screenLocation.
y +
preferredLocation.
y);
} else {
toFind =
mouseEvent.
getLocationOnScreen();
}
GraphicsConfiguration gc =
getDrawingGC(
toFind);
if (
gc == null) {
toFind =
mouseEvent.
getLocationOnScreen();
gc =
getDrawingGC(
toFind);
if (
gc == null) {
gc =
insideComponent.
getGraphicsConfiguration();
}
}
Rectangle sBounds =
gc.
getBounds();
Insets screenInsets =
Toolkit.
getDefaultToolkit()
.
getScreenInsets(
gc);
// Take into account screen insets, decrease viewport
sBounds.
x +=
screenInsets.
left;
sBounds.
y +=
screenInsets.
top;
sBounds.
width -= (
screenInsets.
left +
screenInsets.
right);
sBounds.
height -= (
screenInsets.
top +
screenInsets.
bottom);
boolean
leftToRight
=
SwingUtilities.
isLeftToRight(
insideComponent);
// Just to be paranoid
hideTipWindow();
tip =
insideComponent.
createToolTip();
tip.
setTipText(
toolTipText);
size =
tip.
getPreferredSize();
if(
preferredLocation != null) {
location =
toFind;
if (!
leftToRight) {
location.
x -=
size.
width;
}
} else {
location = new
Point(
screenLocation.
x +
mouseEvent.
getX(),
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 = null;
insideTimer.
stop();
}
}
/**
* Returns a shared <code>ToolTipManager</code> instance.
*
* @return a shared <code>ToolTipManager</code> object
*/
public static
ToolTipManager sharedInstance() {
Object value =
SwingUtilities.
appContextGet(
TOOL_TIP_MANAGER_KEY);
if (
value instanceof
ToolTipManager) {
return (
ToolTipManager)
value;
}
ToolTipManager manager = new
ToolTipManager();
SwingUtilities.
appContextPut(
TOOL_TIP_MANAGER_KEY,
manager);
return
manager;
}
// 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);
component.
removeKeyListener(
accessibilityKeyListener);
component.
addKeyListener(
accessibilityKeyListener);
}
/**
* 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);
component.
removeKeyListener(
accessibilityKeyListener);
}
// 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 &&
insideComponent != null) {
// 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();
// insideComponent may be removed after tooltip is made visible
if (
insideComponentWindow != null) {
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;
}
/* This listener is registered when the tooltip is first registered
* on a component in order to process accessibility keybindings.
* This will apply globally across L&F
*
* Post Tip: Ctrl+F1
* Unpost Tip: Esc and Ctrl+F1
*/
private class
AccessibilityKeyListener extends
KeyAdapter {
public void
keyPressed(
KeyEvent e) {
if (!
e.
isConsumed()) {
JComponent source = (
JComponent)
e.
getComponent();
KeyStroke keyStrokeForEvent =
KeyStroke.
getKeyStrokeForEvent(
e);
if (
hideTip.
equals(
keyStrokeForEvent)) {
if (
tipWindow != null) {
hide(
source);
e.
consume();
}
} else if (
postTip.
equals(
keyStrokeForEvent)) {
// Shown tooltip will be hidden
ToolTipManager.this.
show(
source);
e.
consume();
}
}
}
}
}