Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / javax / swing / ToolTipManager.java
blobc7de4db8330176ca39b03525f980b32610a2baa0
1 /* ToolTipManager.java --
2 Copyright (C) 2002, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package javax.swing;
40 import java.awt.Component;
41 import java.awt.Container;
42 import java.awt.Dimension;
43 import java.awt.Point;
44 import java.awt.event.ActionEvent;
45 import java.awt.event.ActionListener;
46 import java.awt.event.MouseAdapter;
47 import java.awt.event.MouseEvent;
48 import java.awt.event.MouseMotionListener;
50 /**
51 * This class is responsible for the registration of JToolTips to Components
52 * and for displaying them when appropriate.
54 public class ToolTipManager extends MouseAdapter implements MouseMotionListener
56 /**
57 * This ActionListener is associated with the Timer that listens to whether
58 * the JToolTip can be hidden after four seconds.
60 protected class stillInsideTimerAction implements ActionListener
62 /**
63 * This method creates a new stillInsideTimerAction object.
65 protected stillInsideTimerAction()
67 // Nothing to do here.
70 /**
71 * This method hides the JToolTip when the Timer has finished.
73 * @param event The ActionEvent.
75 public void actionPerformed(ActionEvent event)
77 hideTip();
81 /**
82 * This Actionlistener is associated with the Timer that listens to whether
83 * the mouse cursor has re-entered the JComponent in time for an immediate
84 * redisplay of the JToolTip.
86 protected class outsideTimerAction implements ActionListener
88 /**
89 * This method creates a new outsideTimerAction object.
91 protected outsideTimerAction()
93 // Nothing to do here.
96 /**
97 * This method is called when the Timer that listens to whether the mouse
98 * cursor has re-entered the JComponent has run out.
100 * @param event The ActionEvent.
102 public void actionPerformed(ActionEvent event)
104 // TODO: What should be done here, if anything?
109 * This ActionListener is associated with the Timer that listens to whether
110 * it is time for the JToolTip to be displayed after the mouse has entered
111 * the JComponent.
113 protected class insideTimerAction implements ActionListener
116 * This method creates a new insideTimerAction object.
118 protected insideTimerAction()
120 // Nothing to do here.
124 * This method displays the JToolTip when the Mouse has been still for the
125 * delay.
127 * @param event The ActionEvent.
129 public void actionPerformed(ActionEvent event)
131 showTip();
136 * The Timer that determines whether the Mouse has been still long enough
137 * for the JToolTip to be displayed.
139 Timer enterTimer;
142 * The Timer that determines whether the Mouse has re-entered the JComponent
143 * quickly enough for the JToolTip to be displayed immediately.
145 Timer exitTimer;
148 * The Timer that determines whether the JToolTip has been displayed long
149 * enough for it to be hidden.
151 Timer insideTimer;
153 /** A global enabled setting for the ToolTipManager. */
154 private transient boolean enabled = true;
156 /** lightWeightPopupEnabled */
157 protected boolean lightWeightPopupEnabled = true;
159 /** heavyWeightPopupEnabled */
160 protected boolean heavyWeightPopupEnabled = false;
162 /** The shared instance of the ToolTipManager. */
163 private static ToolTipManager shared;
165 /** The current component the tooltip is being displayed for. */
166 private static Component currentComponent;
168 /** The current tooltip. */
169 private static JToolTip currentTip;
171 /** The last known position of the mouse cursor. */
172 private static Point currentPoint;
174 /** */
175 private static Popup popup;
178 * Creates a new ToolTipManager and sets up the timers.
180 ToolTipManager()
182 enterTimer = new Timer(750, new insideTimerAction());
183 enterTimer.setRepeats(false);
185 insideTimer = new Timer(4000, new stillInsideTimerAction());
186 insideTimer.setRepeats(false);
188 exitTimer = new Timer(500, new outsideTimerAction());
189 exitTimer.setRepeats(false);
193 * This method returns the shared instance of ToolTipManager used by all
194 * JComponents.
196 * @return The shared instance of ToolTipManager.
198 public static ToolTipManager sharedInstance()
200 if (shared == null)
201 shared = new ToolTipManager();
203 return shared;
207 * This method sets whether ToolTips are enabled or disabled for all
208 * JComponents.
210 * @param enabled Whether ToolTips are enabled or disabled for all
211 * JComponents.
213 public void setEnabled(boolean enabled)
215 if (! enabled)
217 enterTimer.stop();
218 exitTimer.stop();
219 insideTimer.stop();
222 this.enabled = enabled;
226 * This method returns whether ToolTips are enabled.
228 * @return Whether ToolTips are enabled.
230 public boolean isEnabled()
232 return enabled;
236 * This method returns whether LightweightToolTips are enabled.
238 * @return Whether LighweightToolTips are enabled.
240 public boolean isLightWeightPopupEnabled()
242 return lightWeightPopupEnabled;
246 * This method sets whether LightweightToolTips are enabled. If you mix
247 * Lightweight and Heavyweight components, you must set this to false to
248 * ensure that the ToolTips popup above all other components.
250 * @param enabled Whether LightweightToolTips will be enabled.
252 public void setLightWeightPopupEnabled(boolean enabled)
254 lightWeightPopupEnabled = enabled;
255 heavyWeightPopupEnabled = ! enabled;
259 * This method returns the initial delay before the ToolTip is shown when
260 * the mouse enters a Component.
262 * @return The initial delay before the ToolTip is shown.
264 public int getInitialDelay()
266 return enterTimer.getDelay();
270 * This method sets the initial delay before the ToolTip is shown when the
271 * mouse enters a Component.
273 * @param delay The initial delay before the ToolTip is shown.
275 public void setInitialDelay(int delay)
277 enterTimer.setDelay(delay);
281 * This method returns the time the ToolTip will be shown before being
282 * hidden.
284 * @return The time the ToolTip will be shown before being hidden.
286 public int getDismissDelay()
288 return insideTimer.getDelay();
292 * This method sets the time the ToolTip will be shown before being hidden.
294 * @param delay The time the ToolTip will be shown before being hidden.
296 public void setDismissDelay(int delay)
298 insideTimer.setDelay(delay);
302 * This method returns the amount of delay where if the mouse re-enters a
303 * Component, the tooltip will be shown immediately.
305 * @return The reshow delay.
307 public int getReshowDelay()
309 return exitTimer.getDelay();
313 * This method sets the amount of delay where if the mouse re-enters a
314 * Component, the tooltip will be shown immediately.
316 * @param delay The reshow delay.
318 public void setReshowDelay(int delay)
320 exitTimer.setDelay(delay);
324 * This method registers a JComponent with the ToolTipManager.
326 * @param component The JComponent to register with the ToolTipManager.
328 public void registerComponent(JComponent component)
330 component.addMouseListener(this);
331 component.addMouseMotionListener(this);
335 * This method unregisters a JComponent with the ToolTipManager.
337 * @param component The JComponent to unregister with the ToolTipManager.
339 public void unregisterComponent(JComponent component)
341 component.removeMouseMotionListener(this);
342 component.removeMouseListener(this);
346 * This method is called whenever the mouse enters a JComponent registered
347 * with the ToolTipManager. When the mouse enters within the period of time
348 * specified by the reshow delay, the tooltip will be displayed
349 * immediately. Otherwise, it must wait for the initial delay before
350 * displaying the tooltip.
352 * @param event The MouseEvent.
354 public void mouseEntered(MouseEvent event)
356 if (currentComponent != null
357 && getContentPaneDeepestComponent(event) == currentComponent)
358 return;
359 currentPoint = event.getPoint();
361 currentComponent = (Component) event.getSource();
363 if (exitTimer.isRunning())
365 exitTimer.stop();
366 showTip();
367 return;
369 // This should always be stopped unless we have just fake-exited.
370 if (!enterTimer.isRunning())
371 enterTimer.start();
375 * This method is called when the mouse exits a JComponent registered with the
376 * ToolTipManager. When the mouse exits, the tooltip should be hidden
377 * immediately.
379 * @param event
380 * The MouseEvent.
382 public void mouseExited(MouseEvent event)
384 if (getContentPaneDeepestComponent(event) == currentComponent)
385 return;
387 currentPoint = event.getPoint();
388 currentComponent = null;
389 hideTip();
391 if (! enterTimer.isRunning())
392 exitTimer.start();
393 if (enterTimer.isRunning())
394 enterTimer.stop();
395 if (insideTimer.isRunning())
396 insideTimer.stop();
400 * This method is called when the mouse is pressed on a JComponent
401 * registered with the ToolTipManager. When the mouse is pressed, the
402 * tooltip (if it is shown) must be hidden immediately.
404 * @param event The MouseEvent.
406 public void mousePressed(MouseEvent event)
408 currentPoint = event.getPoint();
409 if (enterTimer.isRunning())
410 enterTimer.restart();
411 else if (insideTimer.isRunning())
413 insideTimer.stop();
414 hideTip();
419 * This method is called when the mouse is dragged in a JComponent
420 * registered with the ToolTipManager.
422 * @param event The MouseEvent.
424 public void mouseDragged(MouseEvent event)
426 currentPoint = event.getPoint();
427 if (enterTimer.isRunning())
428 enterTimer.restart();
432 * This method is called when the mouse is moved in a JComponent registered
433 * with the ToolTipManager.
435 * @param event The MouseEvent.
437 public void mouseMoved(MouseEvent event)
439 currentPoint = event.getPoint();
440 if (enterTimer.isRunning())
441 enterTimer.restart();
445 * This method displays the ToolTip. It can figure out the method needed to
446 * show it as well (whether to display it in heavyweight/lightweight panel
447 * or a window.) This is package-private to avoid an accessor method.
449 void showTip()
451 if (!enabled || currentComponent == null || !currentComponent.isEnabled()
452 || !currentComponent.isShowing())
454 popup = null;
455 return;
458 if (currentTip == null || currentTip.getComponent() != currentComponent
459 && currentComponent instanceof JComponent)
460 currentTip = ((JComponent) currentComponent).createToolTip();
462 Point p = currentPoint;
463 Point cP = currentComponent.getLocationOnScreen();
464 Dimension dims = currentTip.getPreferredSize();
466 JLayeredPane pane = null;
467 JRootPane r = ((JRootPane) SwingUtilities.getAncestorOfClass(JRootPane.class,
468 currentComponent));
469 if (r != null)
470 pane = r.getLayeredPane();
471 if (pane == null)
472 return;
474 p.translate(cP.x, cP.y);
475 adjustLocation(p, pane, dims);
477 currentTip.setBounds(0, 0, dims.width, dims.height);
479 PopupFactory factory = PopupFactory.getSharedInstance();
480 popup = factory.getPopup(currentComponent, currentTip, p.x, p.y);
481 popup.show();
485 * Adjusts the point to a new location on the component,
486 * using the currentTip's dimensions.
488 * @param p - the point to convert.
489 * @param c - the component the point is on.
490 * @param d - the dimensions of the currentTip.
492 private Point adjustLocation(Point p, Component c, Dimension d)
494 if (p.x + d.width > c.getWidth())
495 p.x -= d.width;
496 if (p.x < 0)
497 p.x = 0;
498 if (p.y + d.height < c.getHeight())
499 p.y += d.height;
500 if (p.y + d.height > c.getHeight())
501 p.y -= d.height;
503 return p;
507 * This method hides the ToolTip.
508 * This is package-private to avoid an accessor method.
510 void hideTip()
512 if (popup != null)
513 popup.hide();
517 * This method returns the deepest component in the content pane for the
518 * first RootPaneContainer up from the currentComponent. This method is
519 * used in conjunction with one of the mouseXXX methods.
521 * @param e The MouseEvent.
523 * @return The deepest component in the content pane.
525 private Component getContentPaneDeepestComponent(MouseEvent e)
527 Component source = (Component) e.getSource();
528 Container parent = (Container) SwingUtilities.getAncestorOfClass(JRootPane.class,
529 currentComponent);
530 if (parent == null)
531 return null;
532 parent = ((JRootPane) parent).getContentPane();
533 Point p = e.getPoint();
534 p = SwingUtilities.convertPoint(source, p, parent);
535 Component target = SwingUtilities.getDeepestComponentAt(parent, p.x, p.y);
536 return target;