diff --git a/projects/samskivert/src/java/com/samskivert/swing/ToolTipManager.java b/projects/samskivert/src/java/com/samskivert/swing/ToolTipManager.java new file mode 100644 index 00000000..31754285 --- /dev/null +++ b/projects/samskivert/src/java/com/samskivert/swing/ToolTipManager.java @@ -0,0 +1,221 @@ +// +// $Id: ToolTipManager.java,v 1.1 2001/08/22 08:15:39 shaper Exp $ + +package com.samskivert.swing; + +import javax.swing.SwingUtilities; + +import com.samskivert.Log; +import com.samskivert.util.*; + +/** + * The tool tip manager provides generic facilities for container + * objects to display "tool tips" associated with the objects they + * contain. + * + *

The container object should construct a tool tip manager for + * itself, implement the {@link ToolTipObserver} interface and then + * add calls to {@link #handleMouseEntered}, {@link + * #handleMouseExited}, {@link #handleMouseClicked} and {@link + * #handleMouseMoved} as appropriate within its code to notify the + * manager of relevant user events. + * + *

The manager will then turn around and call {@link + * ToolTipObserver#showToolTip} or {@link ToolTipObserver#hideToolTip} + * as necessary, taking into account standard tool tip timing and + * semantics. + */ +public class ToolTipManager implements Interval +{ + /** + * Construct a tool tip manager for the given observer. + * + * @param obs the tool tip observer. + */ + public ToolTipManager (ToolTipObserver obs) + { + _obs = obs; + _lastmove = System.currentTimeMillis(); + _fastshow = false; + _tipdelay = TIP_INTERVAL; + + // register ourselves with the interval manager + IntervalManager.register(this, TIP_INTERVAL, null, true); + } + + /** + * Called by the IntervalManager whenever our + * interval expires. + */ + public void intervalExpired (int id, Object arg) + { + // disable fast tool tip display if we've been outside of an + // object for sufficiently long + if (_fastshow && _curobj == null) { + long now = System.currentTimeMillis(); + _fastshow = (now - _lastmove < _tipdelay); + } + + // show or hide the tool tip as appropriate + handleTipAction(); + } + + /** + * Handle showing or hiding a tip as necessary. + */ + protected void handleTipAction () + { + // bail if there's nothing doing + if (_action == A_NONE) return; + + // do nothing if it's not yet time for us to act + if (!isShowTime()) return; + + // throw a task on the AWT thread to handle tip actions + SwingUtilities.invokeLater(new TipTask(_curobj, _action)); + + // clear out our action state + _action = A_NONE; + + // speed future tool tips on their way + _fastshow = true; + } + + /** + * Return whether sufficient time has passed since the last mouse + * movement to allow us to show a tool tip. + */ + protected boolean isShowTime () + { + long now = System.currentTimeMillis(); + return (_fastshow || (now - _lastmove >= _tipdelay)); + } + + protected void updateObject (Object target) + { + _curobj = target; + _lastmove = System.currentTimeMillis(); + + // update tip display immediately if the time is right + handleTipAction(); + } + + /** + * Handle mouse entered events for a given object. The {@link + * ToolTipObserver} should call this method whenever an object it + * manages is entered. + * + * @param target the object entered. + */ + public void handleMouseEntered (Object target) + { + _action = A_SHOW; + updateObject(target); + } + + /** + * Handle mouse exited events for a given object. The {@link + * ToolTipObserver} should call this method whenever an object it + * manages is exited. + * + * @param target the object exited. + */ + public void handleMouseExited (Object target) + { + _action = A_HIDE; + updateObject(null); + } + + /** + * Handle mouse clicked events for a given object. The {@link + * ToolTipObserver} should call this method whenever an object it + * manages is clicked on. + * + * @param target the object clicked on. + */ + public void handleMouseClicked (Object target) + { + _action = A_HIDE; + updateObject(target); + + // disable fast tip display on mouse-click + _fastshow = false; + } + + /** + * Handle mouse moved events. The {@link ToolTipObserver} should + * call this method whenever the mouse is moved within its + * container bounds. + */ + public void handleMouseMoved () + { + // just update the last moved time since we don't perform any + // tip antics purely as a result of mouse movement + _lastmove = System.currentTimeMillis(); + } + + /** + * Set the milliseconds to wait before showing a tool tip. + * + * @param delay the milliseconds to wait. + */ + public void setShowDelay (int delay) + { + if (delay < TIP_INTERVAL) { + Log.warning("Tip show delay must be >= " + TIP_INTERVAL + " ms."); + return; + } + + _tipdelay = delay; + } + + /** + * A class to encapsulate tool tip observer notification to be + * performed on the AWT thread. + */ + class TipTask implements Runnable + { + public TipTask (Object obj, int action) + { + _obj = obj; + _action = action; + } + + public void run () + { + switch (_action) { + case A_SHOW: _obs.showToolTip(_obj); break; + case A_HIDE: _obs.hideToolTip(); break; + } + } + + protected Object _obj; + protected int _action; + } + + /** Delay in milliseconds between intervals. */ + protected static final int TIP_INTERVAL = 1000; + + /** Action constants. */ + protected static final int A_NONE = 0; + protected static final int A_SHOW = 1; + protected static final int A_HIDE = 2; + + /** The minimum delay in milliseconds before showing a tip. */ + protected long _tipdelay; + + /** The last time a mouse move we care about was made. */ + protected long _lastmove; + + /** The current object the mouse is within. */ + protected Object _curobj; + + /** The next tool tip action to perform. */ + protected int _action; + + /** Whether tips should be shown quickly due to other recent tips. */ + protected boolean _fastshow; + + /** The tool tip observer. */ + protected ToolTipObserver _obs; +} diff --git a/projects/samskivert/src/java/com/samskivert/swing/ToolTipObserver.java b/projects/samskivert/src/java/com/samskivert/swing/ToolTipObserver.java new file mode 100644 index 00000000..b9ba40c6 --- /dev/null +++ b/projects/samskivert/src/java/com/samskivert/swing/ToolTipObserver.java @@ -0,0 +1,26 @@ +// +// $Id: ToolTipObserver.java,v 1.1 2001/08/22 08:15:39 shaper Exp $ + +package com.samskivert.swing; + +/** + * An interface to be implemented by container objects that would like + * to be notified by the {@link ToolTipManager} when they should + * display tool tips associated with the objects that they manage. + */ +public interface ToolTipObserver +{ + /** + * Called when the tool tip associated with the given target + * should be displayed. + * + * @param target the object whose tool tip should be shown. + */ + public void showToolTip (Object target); + + /** + * Called when any visible tool tip should be hidden and so the + * observer is likely to want to repaint itself without the tip. + */ + public void hideToolTip (); +}