home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 November
/
Chip_1998-11_cd.bin
/
tema
/
Cafe
/
jfc.bin
/
ToolTipManager.java
< prev
next >
Wrap
Text File
|
1998-02-26
|
14KB
|
460 lines
/*
* @(#)ToolTipManager.java 1.24 98/01/30
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of Sun
* Microsystems, Inc. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Sun.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.sun.java.swing;
import java.awt.event.*;
import java.awt.*;
/**
* Manages all the ToolTips in the system.
*
* @see JComponent#createToolTip
* @version 1.24 01/30/98
* @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();
Popup tipWindow;
JToolTip tip;
boolean enabled = true;
boolean mouseAboveToolTip = false;
private static final int INIT_POPUP = 0;
private static final int MEDIUM_POPUP = 1;
private static final int HEAVY_POPUP = 2;
private int tipType = INIT_POPUP;
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);
}
public void setEnabled(boolean flag) {
enabled = flag;
if (!flag) {
hideTipWindow();
}
}
public boolean isEnabled() {
return enabled;
}
public void setInitialDelay(int microSeconds) {
enterTimer.setInitialDelay(microSeconds);
}
public int getInitialDelay() {
return enterTimer.getInitialDelay();
}
public void setDismissDelay(int microSeconds) {
insideTimer.setDelay(microSeconds);
}
public int getDismissDelay() {
return insideTimer.getDelay();
}
public void setReshowDelay(int microSeconds) {
exitTimer.setDelay(microSeconds);
}
public int getReshowDelay() {
return exitTimer.getDelay();
}
void showTipWindow() {
if(insideComponent == null || !insideComponent.isShowing())
return;
if (enabled) {
Dimension size;
Point screenLocation = insideComponent.getLocationOnScreen();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Point location = new Point();
// Just to be paranoid
hideTipWindow();
tip = insideComponent.createToolTip();
tip.setTipText(toolTipText);
size = tip.getPreferredSize();
/* REMIND: should recycle these - L&F doesn't seem to
* be working in browsers when using a Panel
*/
switch (tipType){
case INIT_POPUP:
Container parent;
for (parent = insideComponent.getParent(); parent != null; parent = parent.getParent()){
if (parent instanceof JApplet){
tipType = MEDIUM_POPUP;
tipWindow = new PanelPopup(tip, size);
}
}
if (tipType == INIT_POPUP)
{
tipWindow = new WindowPopup((frameForComponent(insideComponent)),tip,size);
tipType = HEAVY_POPUP;
}
break;
case HEAVY_POPUP:
tipWindow = new WindowPopup((frameForComponent(insideComponent)),tip,size);
break;
case MEDIUM_POPUP:
tipWindow = new PanelPopup(tip,size);
break;
default:
tipWindow = new WindowPopup((frameForComponent(insideComponent)),tip,size);
break;
}
tipWindow.addMouseListener(this);
if(preferredLocation != null) {
location.x = screenLocation.x + preferredLocation.x;
location.y = screenLocation.y + preferredLocation.y;
} else {
location.x = screenLocation.x + mouseEvent.getX();
location.y = screenLocation.y + mouseEvent.getY() + 20;
if (location.x + size.width > screenSize.width) {
location.x -= size.width;
}
if (location.y + size.height > screenSize.height) {
location.y -= (size.height + 20);
}
}
tipWindow.show(insideComponent,location.x,location.y);
insideTimer.start();
}
}
void hideTipWindow() {
if (tipWindow != null) {
tipWindow.removeMouseListener(this);
tipWindow.hide();
tipWindow = null;
(tip.getUI()).uninstallUI(tip);
tip = null;
insideTimer.stop();
}
}
public static ToolTipManager sharedInstance() {
return sharedInstance;
}
public void registerComponent(JComponent component) {
component.removeMouseListener(this);
component.addMouseListener(this);
}
public void unregisterComponent(JComponent component) {
component.removeMouseListener(this);
}
public void mouseEntered(MouseEvent event) {
if(event.getSource() == tipWindow)
return;
JComponent component = (JComponent)event.getSource();
toolTipText = component.getToolTipText(event);
preferredLocation = component.getToolTipLocation(event);
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();
insideComponent = null;
}
component.addMouseMotionListener(this);
insideComponent = component;
if (toolTipText != null) {
mouseEvent = event;
if (showImmediately) {
showTipWindow();
} else {
enterTimer.start();
}
}
}
public void mouseExited(MouseEvent event) {
boolean shouldHide = true;
if (insideComponent == null) {
// Drag exit
}
if(event.getSource() == tipWindow) {
Container insideComponentWindow = insideComponent.getTopLevelAncestor();
Rectangle b = tipWindow.getBounds();
Point location = event.getPoint();
location.x += b.x;
location.y += b.y;
b = insideComponentWindow.getBounds();
location.x -= b.x;
location.y -= b.y;
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) {
Point location = SwingUtilities.convertPoint(insideComponent,
event.getPoint(),
null);
Rectangle bounds = insideComponent.getTopLevelAncestor().getBounds();
location.x += bounds.x;
location.y += bounds.y;
bounds = tipWindow.getBounds();
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.start();
}
}
public void mousePressed(MouseEvent event) {
hideTipWindow();
enterTimer.stop();
showImmediately = false;
}
public void mouseDragged(MouseEvent event) {
}
public void mouseMoved(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();
} else {
enterTimer.restart();
}
}
} else {
toolTipText = null;
preferredLocation = null;
mouseEvent = null;
hideTipWindow();
enterTimer.stop();
exitTimer.start();
}
}
protected class insideTimerAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
if(insideComponent != null && insideComponent.isShowing()) {
showImmediately = true;
showTipWindow();
}
}
}
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;
}
}
static Frame frameForComponent(Component component) {
while (!(component instanceof Frame)) {
component = component.getParent();
}
return (Frame)component;
}
/*
* The following interface describes what a popup should implement.
* We do this because the ToolTip manager uses popup that can be windows or
* panels. The reason is two-fold: Navigator does not display Windows properly,
* and there is a problem with layout when using a Panel with
* Java Apps on the Solaris VM which doesn't occur in Applets or on Win32 VM apps.
* Solaris also has some strange behaviour with extra MOUSE_EXIT events when
* using a Panel which required a different workaround, hence Windows for Apps,
* Panels for Applets.
*/
private interface Popup {
public void show(JComponent invoker, int x, int y);
public void hide();
public void addMouseListener(ToolTipManager c);
public void removeMouseListener(ToolTipManager c);
public Rectangle getBounds();
}
// MEDIUM
class PanelPopup extends Panel implements Popup {
public PanelPopup(JComponent t, Dimension s) {
super();
setLayout(new BorderLayout());
add(t, BorderLayout.CENTER);
setSize(s);
}
public Rectangle getBounds(){
return super.getBounds();
}
public void show(JComponent invoker, int x, int y) {
Point p = new Point(x,y);
SwingUtilities.convertPointFromScreen(p,invoker.getRootPane().getLayeredPane());
this.setBounds(p.x,p.y,getSize().width, getSize().height);
invoker.getRootPane().getLayeredPane().add(this,JLayeredPane.POPUP_LAYER,0);
}
public void hide() {
Container parent = getParent();
Rectangle r = this.getBounds();
if(parent != null)
parent.remove(this);
parent.repaint(r.x,r.y,r.width,r.height);
}
public void addMouseListener(ToolTipManager c){
super.addMouseListener(c);
}
public void removeMouseListener(ToolTipManager c){
super.removeMouseListener(c);
}
}
// HEAVY
class WindowPopup extends Window implements Popup {
boolean firstShow = true;
public WindowPopup(Frame f,JComponent t, Dimension size) {
super(f);
add(t);
setSize(size);
}
public Rectangle getBounds(){
return super.getBounds();
}
public void show(JComponent invoker, int x, int y) {
this.setBounds(x,y, getSize().width,getSize().height);
this.setLocation(x,y);
this.setVisible(true);
/** This hack is to workaround a bug on Solaris where the windows does not really show
* the first time
*/
if(firstShow) {
this.hide();
this.setVisible(true);
firstShow = false;
}
}
public void hide() {
super.hide();
/** We need to call removeNotify() here because hide() does something only if
* Component.visible is true. When the app frame is miniaturized, the parent
* frame of this frame is invisible, causing AWT to believe that this frame
* is invisible and causing hide() to do nothing
*/
removeNotify();
}
public void addMouseListener(ToolTipManager c){
super.addMouseListener(c);
}
public void removeMouseListener(ToolTipManager c){
super.removeMouseListener(c);
}
}
}