mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			594 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			594 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Java
		
	
	
	
/* ToolTipManager.java --
 | 
						|
   Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
 | 
						|
 | 
						|
This file is part of GNU Classpath.
 | 
						|
 | 
						|
GNU Classpath is free software; you can redistribute it and/or modify
 | 
						|
it under the terms of the GNU General Public License as published by
 | 
						|
the Free Software Foundation; either version 2, or (at your option)
 | 
						|
any later version.
 | 
						|
 | 
						|
GNU Classpath is distributed in the hope that it will be useful, but
 | 
						|
WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
General Public License for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License
 | 
						|
along with GNU Classpath; see the file COPYING.  If not, write to the
 | 
						|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
						|
02110-1301 USA.
 | 
						|
 | 
						|
Linking this library statically or dynamically with other modules is
 | 
						|
making a combined work based on this library.  Thus, the terms and
 | 
						|
conditions of the GNU General Public License cover the whole
 | 
						|
combination.
 | 
						|
 | 
						|
As a special exception, the copyright holders of this library give you
 | 
						|
permission to link this library with independent modules to produce an
 | 
						|
executable, regardless of the license terms of these independent
 | 
						|
modules, and to copy and distribute the resulting executable under
 | 
						|
terms of your choice, provided that you also meet, for each linked
 | 
						|
independent module, the terms and conditions of the license of that
 | 
						|
module.  An independent module is a module which is not derived from
 | 
						|
or based on this library.  If you modify this library, you may extend
 | 
						|
this exception to your version of the library, but you are not
 | 
						|
obligated to do so.  If you do not wish to do so, delete this
 | 
						|
exception statement from your version. */
 | 
						|
 | 
						|
package javax.swing;
 | 
						|
 | 
						|
import java.awt.Component;
 | 
						|
import java.awt.Container;
 | 
						|
import java.awt.Dimension;
 | 
						|
import java.awt.Point;
 | 
						|
import java.awt.event.ActionEvent;
 | 
						|
import java.awt.event.ActionListener;
 | 
						|
import java.awt.event.MouseAdapter;
 | 
						|
import java.awt.event.MouseEvent;
 | 
						|
import java.awt.event.MouseMotionListener;
 | 
						|
 | 
						|
/**
 | 
						|
 * This class is responsible for the registration of JToolTips to Components
 | 
						|
 * and for displaying them when appropriate.
 | 
						|
 */
 | 
						|
public class ToolTipManager extends MouseAdapter implements MouseMotionListener
 | 
						|
{
 | 
						|
  /**
 | 
						|
   * This ActionListener is associated with the Timer that listens to whether
 | 
						|
   * the JToolTip can be hidden after four seconds.
 | 
						|
   */
 | 
						|
  protected class stillInsideTimerAction implements ActionListener
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * This method creates a new stillInsideTimerAction object.
 | 
						|
     */
 | 
						|
    protected stillInsideTimerAction()
 | 
						|
    {
 | 
						|
      // Nothing to do here.
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * This method hides the JToolTip when the Timer has finished.
 | 
						|
     *
 | 
						|
     * @param event The ActionEvent.
 | 
						|
     */
 | 
						|
    public void actionPerformed(ActionEvent event)
 | 
						|
    {
 | 
						|
      hideTip();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This Actionlistener is associated with the Timer that listens to whether
 | 
						|
   * the mouse cursor has re-entered the JComponent in time for an immediate
 | 
						|
   * redisplay of the JToolTip.
 | 
						|
   */
 | 
						|
  protected class outsideTimerAction implements ActionListener
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * This method creates a new outsideTimerAction object.
 | 
						|
     */
 | 
						|
    protected outsideTimerAction()
 | 
						|
    {
 | 
						|
      // Nothing to do here.
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * This method is called when the Timer that listens to whether the mouse
 | 
						|
     * cursor has re-entered the JComponent has run out.
 | 
						|
     *
 | 
						|
     * @param event The ActionEvent.
 | 
						|
     */
 | 
						|
    public void actionPerformed(ActionEvent event)
 | 
						|
    {
 | 
						|
      // TODO: What should be done here, if anything?
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This ActionListener is associated with the Timer that listens to whether
 | 
						|
   * it is time for the JToolTip to be displayed after the mouse has entered
 | 
						|
   * the JComponent.
 | 
						|
   */
 | 
						|
  protected class insideTimerAction implements ActionListener
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * This method creates a new insideTimerAction object.
 | 
						|
     */
 | 
						|
    protected insideTimerAction()
 | 
						|
    {
 | 
						|
      // Nothing to do here.
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * This method displays the JToolTip when the Mouse has been still for the
 | 
						|
     * delay.
 | 
						|
     *
 | 
						|
     * @param event The ActionEvent.
 | 
						|
     */
 | 
						|
    public void actionPerformed(ActionEvent event)
 | 
						|
    {
 | 
						|
      showTip();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The Timer that determines whether the Mouse has been still long enough
 | 
						|
   * for the JToolTip to be displayed.
 | 
						|
   */
 | 
						|
  Timer enterTimer;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The Timer that determines whether the Mouse has re-entered the JComponent
 | 
						|
   * quickly enough for the JToolTip to be displayed immediately.
 | 
						|
   */
 | 
						|
  Timer exitTimer;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The Timer that determines whether the JToolTip has been displayed long
 | 
						|
   * enough for it to be hidden.
 | 
						|
   */
 | 
						|
  Timer insideTimer;
 | 
						|
 | 
						|
  /** A global enabled setting for the ToolTipManager. */
 | 
						|
  private transient boolean enabled = true;
 | 
						|
 | 
						|
  /** lightWeightPopupEnabled */
 | 
						|
  protected boolean lightWeightPopupEnabled = true;
 | 
						|
 | 
						|
  /** heavyWeightPopupEnabled */
 | 
						|
  protected boolean heavyWeightPopupEnabled = false;
 | 
						|
 | 
						|
  /** The shared instance of the ToolTipManager. */
 | 
						|
  private static ToolTipManager shared;
 | 
						|
 | 
						|
  /** The current component the tooltip is being displayed for. */
 | 
						|
  private JComponent currentComponent;
 | 
						|
 | 
						|
  /** The current tooltip. */
 | 
						|
  private JToolTip currentTip;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The tooltip text.
 | 
						|
   */
 | 
						|
  private String toolTipText;
 | 
						|
 | 
						|
  /** The last known position of the mouse cursor. */
 | 
						|
  private Point currentPoint;
 | 
						|
 | 
						|
  /**  */
 | 
						|
  private Popup popup;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Creates a new ToolTipManager and sets up the timers.
 | 
						|
   */
 | 
						|
  ToolTipManager()
 | 
						|
  {
 | 
						|
    enterTimer = new Timer(750, new insideTimerAction());
 | 
						|
    enterTimer.setRepeats(false);
 | 
						|
 | 
						|
    insideTimer = new Timer(4000, new stillInsideTimerAction());
 | 
						|
    insideTimer.setRepeats(false);
 | 
						|
 | 
						|
    exitTimer = new Timer(500, new outsideTimerAction());
 | 
						|
    exitTimer.setRepeats(false);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method returns the shared instance of ToolTipManager used by all
 | 
						|
   * JComponents.
 | 
						|
   *
 | 
						|
   * @return The shared instance of ToolTipManager.
 | 
						|
   */
 | 
						|
  public static ToolTipManager sharedInstance()
 | 
						|
  {
 | 
						|
    if (shared == null)
 | 
						|
      shared = new ToolTipManager();
 | 
						|
 | 
						|
    return shared;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method sets whether ToolTips are enabled or disabled for all
 | 
						|
   * JComponents.
 | 
						|
   *
 | 
						|
   * @param enabled Whether ToolTips are enabled or disabled for all
 | 
						|
   *        JComponents.
 | 
						|
   */
 | 
						|
  public void setEnabled(boolean enabled)
 | 
						|
  {
 | 
						|
    if (! enabled)
 | 
						|
      {
 | 
						|
        enterTimer.stop();
 | 
						|
        exitTimer.stop();
 | 
						|
        insideTimer.stop();
 | 
						|
      }
 | 
						|
 | 
						|
    this.enabled = enabled;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method returns whether ToolTips are enabled.
 | 
						|
   *
 | 
						|
   * @return Whether ToolTips are enabled.
 | 
						|
   */
 | 
						|
  public boolean isEnabled()
 | 
						|
  {
 | 
						|
    return enabled;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method returns whether LightweightToolTips are enabled.
 | 
						|
   *
 | 
						|
   * @return Whether LighweightToolTips are enabled.
 | 
						|
   */
 | 
						|
  public boolean isLightWeightPopupEnabled()
 | 
						|
  {
 | 
						|
    return lightWeightPopupEnabled;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method sets whether LightweightToolTips are enabled. If you mix
 | 
						|
   * Lightweight and Heavyweight components, you must set this to false to
 | 
						|
   * ensure that the ToolTips popup above all other components.
 | 
						|
   *
 | 
						|
   * @param enabled Whether LightweightToolTips will be enabled.
 | 
						|
   */
 | 
						|
  public void setLightWeightPopupEnabled(boolean enabled)
 | 
						|
  {
 | 
						|
    lightWeightPopupEnabled = enabled;
 | 
						|
    heavyWeightPopupEnabled = ! enabled;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method returns the initial delay before the ToolTip is shown when
 | 
						|
   * the mouse enters a Component.
 | 
						|
   *
 | 
						|
   * @return The initial delay before the ToolTip is shown.
 | 
						|
   */
 | 
						|
  public int getInitialDelay()
 | 
						|
  {
 | 
						|
    return enterTimer.getDelay();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the initial delay before the ToolTip is shown when the
 | 
						|
   * mouse enters a Component.
 | 
						|
   *
 | 
						|
   * @param delay The initial delay before the ToolTip is shown.
 | 
						|
   *
 | 
						|
   * @throws IllegalArgumentException if <code>delay</code> is less than zero.
 | 
						|
   */
 | 
						|
  public void setInitialDelay(int delay)
 | 
						|
  {
 | 
						|
    enterTimer.setDelay(delay);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method returns the time the ToolTip will be shown before being
 | 
						|
   * hidden.
 | 
						|
   *
 | 
						|
   * @return The time the ToolTip will be shown before being hidden.
 | 
						|
   */
 | 
						|
  public int getDismissDelay()
 | 
						|
  {
 | 
						|
    return insideTimer.getDelay();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the time the ToolTip will be shown before being hidden.
 | 
						|
   *
 | 
						|
   * @param delay  the delay (in milliseconds) before tool tips are hidden.
 | 
						|
   *
 | 
						|
   * @throws IllegalArgumentException if <code>delay</code> is less than zero.
 | 
						|
   */
 | 
						|
  public void setDismissDelay(int delay)
 | 
						|
  {
 | 
						|
    insideTimer.setDelay(delay);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method returns the amount of delay where if the mouse re-enters a
 | 
						|
   * Component, the tooltip will be shown immediately.
 | 
						|
   *
 | 
						|
   * @return The reshow delay.
 | 
						|
   */
 | 
						|
  public int getReshowDelay()
 | 
						|
  {
 | 
						|
    return exitTimer.getDelay();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the amount of delay where if the mouse re-enters a
 | 
						|
   * Component, the tooltip will be shown immediately.
 | 
						|
   *
 | 
						|
   * @param delay The reshow delay (in milliseconds).
 | 
						|
   *
 | 
						|
   * @throws IllegalArgumentException if <code>delay</code> is less than zero.
 | 
						|
   */
 | 
						|
  public void setReshowDelay(int delay)
 | 
						|
  {
 | 
						|
    exitTimer.setDelay(delay);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method registers a JComponent with the ToolTipManager.
 | 
						|
   *
 | 
						|
   * @param component The JComponent to register with the ToolTipManager.
 | 
						|
   */
 | 
						|
  public void registerComponent(JComponent component)
 | 
						|
  {
 | 
						|
    component.addMouseListener(this);
 | 
						|
    component.addMouseMotionListener(this);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method unregisters a JComponent with the ToolTipManager.
 | 
						|
   *
 | 
						|
   * @param component The JComponent to unregister with the ToolTipManager.
 | 
						|
   */
 | 
						|
  public void unregisterComponent(JComponent component)
 | 
						|
  {
 | 
						|
    component.removeMouseMotionListener(this);
 | 
						|
    component.removeMouseListener(this);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method is called whenever the mouse enters a JComponent registered
 | 
						|
   * with the ToolTipManager. When the mouse enters within the period of time
 | 
						|
   * specified by the reshow delay, the tooltip will be displayed
 | 
						|
   * immediately. Otherwise, it must wait for the initial delay before
 | 
						|
   * displaying the tooltip.
 | 
						|
   *
 | 
						|
   * @param event The MouseEvent.
 | 
						|
   */
 | 
						|
  public void mouseEntered(MouseEvent event)
 | 
						|
  {
 | 
						|
    if (currentComponent != null
 | 
						|
        && getContentPaneDeepestComponent(event) == currentComponent)
 | 
						|
      return;
 | 
						|
    currentPoint = event.getPoint();
 | 
						|
 | 
						|
    currentComponent = (JComponent) event.getSource();
 | 
						|
    toolTipText = currentComponent.getToolTipText(event);
 | 
						|
    if (exitTimer.isRunning())
 | 
						|
      {
 | 
						|
        exitTimer.stop();
 | 
						|
        showTip();
 | 
						|
        return;
 | 
						|
      }
 | 
						|
    // This should always be stopped unless we have just fake-exited.
 | 
						|
    if (!enterTimer.isRunning())
 | 
						|
      enterTimer.start();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method is called when the mouse exits a JComponent registered with the
 | 
						|
   * ToolTipManager. When the mouse exits, the tooltip should be hidden
 | 
						|
   * immediately.
 | 
						|
   *
 | 
						|
   * @param event
 | 
						|
   *          The MouseEvent.
 | 
						|
   */
 | 
						|
  public void mouseExited(MouseEvent event)
 | 
						|
  {
 | 
						|
    if (getContentPaneDeepestComponent(event) == currentComponent)
 | 
						|
      return;
 | 
						|
 | 
						|
    currentPoint = event.getPoint();
 | 
						|
    currentComponent = null;
 | 
						|
    hideTip();
 | 
						|
 | 
						|
    if (! enterTimer.isRunning())
 | 
						|
      exitTimer.start();
 | 
						|
    if (enterTimer.isRunning())
 | 
						|
      enterTimer.stop();
 | 
						|
    if (insideTimer.isRunning())
 | 
						|
      insideTimer.stop();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method is called when the mouse is pressed on a JComponent
 | 
						|
   * registered with the ToolTipManager. When the mouse is pressed, the
 | 
						|
   * tooltip (if it is shown) must be hidden immediately.
 | 
						|
   *
 | 
						|
   * @param event The MouseEvent.
 | 
						|
   */
 | 
						|
  public void mousePressed(MouseEvent event)
 | 
						|
  {
 | 
						|
    currentPoint = event.getPoint();
 | 
						|
    if (enterTimer.isRunning())
 | 
						|
      enterTimer.restart();
 | 
						|
    else if (insideTimer.isRunning())
 | 
						|
      {
 | 
						|
        insideTimer.stop();
 | 
						|
        hideTip();
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method is called when the mouse is dragged in a JComponent
 | 
						|
   * registered with the ToolTipManager.
 | 
						|
   *
 | 
						|
   * @param event The MouseEvent.
 | 
						|
   */
 | 
						|
  public void mouseDragged(MouseEvent event)
 | 
						|
  {
 | 
						|
    currentPoint = event.getPoint();
 | 
						|
    if (enterTimer.isRunning())
 | 
						|
      enterTimer.restart();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method is called when the mouse is moved in a JComponent registered
 | 
						|
   * with the ToolTipManager.
 | 
						|
   *
 | 
						|
   * @param event The MouseEvent.
 | 
						|
   */
 | 
						|
  public void mouseMoved(MouseEvent event)
 | 
						|
  {
 | 
						|
    currentPoint = event.getPoint();
 | 
						|
    if (currentTip != null && currentTip.isShowing())
 | 
						|
      checkTipUpdate(event);
 | 
						|
    else
 | 
						|
      {
 | 
						|
        if (enterTimer.isRunning())
 | 
						|
          enterTimer.restart();
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Checks if the tooltip's text or location changes when the mouse is moved
 | 
						|
   * over the component.
 | 
						|
   */
 | 
						|
  private void checkTipUpdate(MouseEvent ev)
 | 
						|
  {
 | 
						|
    JComponent comp = (JComponent) ev.getSource();
 | 
						|
    String newText = comp.getToolTipText(ev);
 | 
						|
    String oldText = toolTipText;
 | 
						|
    if (newText != null)
 | 
						|
      {
 | 
						|
        if (((newText != null && newText.equals(oldText)) || newText == null))
 | 
						|
          {
 | 
						|
            // No change at all. Restart timers.
 | 
						|
            if (popup == null)
 | 
						|
              enterTimer.restart();
 | 
						|
            else
 | 
						|
              insideTimer.restart();
 | 
						|
          }
 | 
						|
        else
 | 
						|
          {
 | 
						|
            // Update the tooltip.
 | 
						|
            toolTipText = newText;
 | 
						|
            hideTip();
 | 
						|
            showTip();
 | 
						|
            exitTimer.stop();
 | 
						|
          }
 | 
						|
      }
 | 
						|
    else
 | 
						|
      {
 | 
						|
        // Hide tooltip.
 | 
						|
        currentTip = null;
 | 
						|
        currentPoint = null;
 | 
						|
        hideTip();
 | 
						|
        enterTimer.stop();
 | 
						|
        exitTimer.stop();
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method displays the ToolTip. It can figure out the method needed to
 | 
						|
   * show it as well (whether to display it in heavyweight/lightweight panel
 | 
						|
   * or a window.)  This is package-private to avoid an accessor method.
 | 
						|
   */
 | 
						|
  void showTip()
 | 
						|
  {
 | 
						|
    if (!enabled || currentComponent == null || !currentComponent.isEnabled()
 | 
						|
        || !currentComponent.isShowing())
 | 
						|
      {
 | 
						|
        popup = null;
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
    if (currentTip == null || currentTip.getComponent() != currentComponent)
 | 
						|
      currentTip = currentComponent.createToolTip();
 | 
						|
    currentTip.setTipText(toolTipText);
 | 
						|
 | 
						|
    Point p = currentPoint;
 | 
						|
    Point cP = currentComponent.getLocationOnScreen();
 | 
						|
    Dimension dims = currentTip.getPreferredSize();
 | 
						|
 | 
						|
    JLayeredPane pane = null;
 | 
						|
    JRootPane r = ((JRootPane) SwingUtilities.getAncestorOfClass(JRootPane.class,
 | 
						|
                                                                 currentComponent));
 | 
						|
    if (r != null)
 | 
						|
      pane = r.getLayeredPane();
 | 
						|
    if (pane == null)
 | 
						|
      return;
 | 
						|
 | 
						|
    p.translate(cP.x, cP.y);
 | 
						|
    adjustLocation(p, pane, dims);
 | 
						|
 | 
						|
    currentTip.setBounds(0, 0, dims.width, dims.height);
 | 
						|
 | 
						|
    PopupFactory factory = PopupFactory.getSharedInstance();
 | 
						|
    popup = factory.getPopup(currentComponent, currentTip, p.x, p.y);
 | 
						|
    popup.show();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Adjusts the point to a new location on the component,
 | 
						|
   * using the currentTip's dimensions.
 | 
						|
   *
 | 
						|
   * @param p - the point to convert.
 | 
						|
   * @param c - the component the point is on.
 | 
						|
   * @param d - the dimensions of the currentTip.
 | 
						|
   */
 | 
						|
  private Point adjustLocation(Point p, Component c, Dimension d)
 | 
						|
  {
 | 
						|
    if (p.x + d.width > c.getWidth())
 | 
						|
      p.x -= d.width;
 | 
						|
    if (p.x < 0)
 | 
						|
      p.x = 0;
 | 
						|
    if (p.y + d.height < c.getHeight())
 | 
						|
      p.y += d.height;
 | 
						|
    if (p.y + d.height > c.getHeight())
 | 
						|
      p.y -= d.height;
 | 
						|
 | 
						|
    return p;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method hides the ToolTip.
 | 
						|
   * This is package-private to avoid an accessor method.
 | 
						|
   */
 | 
						|
  void hideTip()
 | 
						|
  {
 | 
						|
    if (popup != null)
 | 
						|
      popup.hide();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method returns the deepest component in the content pane for the
 | 
						|
   * first RootPaneContainer up from the currentComponent. This method is
 | 
						|
   * used in conjunction with one of the mouseXXX methods.
 | 
						|
   *
 | 
						|
   * @param e The MouseEvent.
 | 
						|
   *
 | 
						|
   * @return The deepest component in the content pane.
 | 
						|
   */
 | 
						|
  private Component getContentPaneDeepestComponent(MouseEvent e)
 | 
						|
  {
 | 
						|
    Component source = (Component) e.getSource();
 | 
						|
    Container parent = SwingUtilities.getAncestorOfClass(JRootPane.class,
 | 
						|
                                                         currentComponent);
 | 
						|
    if (parent == null)
 | 
						|
      return null;
 | 
						|
    parent = ((JRootPane) parent).getContentPane();
 | 
						|
    Point p = e.getPoint();
 | 
						|
    p = SwingUtilities.convertPoint(source, p, parent);
 | 
						|
    Component target = SwingUtilities.getDeepestComponentAt(parent, p.x, p.y);
 | 
						|
    return target;
 | 
						|
  }
 | 
						|
}
 |