home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 14 / CDACTUAL.iso / cdactual / demobin / share / os2 / edm2 / 0506 / grinding3.java < prev    next >
Encoding:
Java Source  |  1997-06-01  |  12.6 KB  |  271 lines

  1. package GUITools;
  2.  
  3. import java.AWT.*;
  4. import java.AWT.event.*;
  5. import java.util.Vector;
  6.  
  7. /**
  8.  * The Tooltip class was developed for use by the DockableToolbar class,
  9.  * I chose to make it public since i feel that with slight modification
  10.  * it can be used in other classes.
  11.  * This class doesnt have a simple API (mostly because it was developed
  12.  * for internal use), it has a more generic wrapper (class Hints) which I reccomend on using.
  13.  * This class draws a yellow label tooltip (or hint/hovering help...).
  14.  * The Tooltip class only displays a tooltip at a given X,Y location in
  15.  * A container, if that container has Components in it that hide the tooltip
  16.  * it will try to display on them too. The mouse functionality and the full
  17.  * capabilities of a Tooltip are not implemented here, I will probably subclass
  18.  * this class in a later stage to create an automatic Tooltip facility.
  19.  * This class was developed to run under JDK 1.1.1, with very little assistance
  20.  * from VisualAge for Java, most of the work was done using javac.
  21.  * This class was written by Shai Almog 5/4/97. The sorce is in the public
  22.  * domain and may be modified and used freely. It is not a requirment but
  23.  * I would consider it good manners if you credit me and EDM/2 (www.edm2.com)
  24.  * in applications in which this code was used ;-)
  25. **/
  26.  
  27. public class Tooltip extends Canvas
  28. // The reason we extend Canvas and not Component
  29. // is due to a bug in VisualAge for Java which did not allow this.
  30. {
  31.      /**
  32.      * The Tooltip constructor takes the following parameters
  33.      * caption - the text of the tooltip.
  34.      * tooltipFont - the font of the tooltip.
  35.      * c - The Container on which the Tooltip will be displayed.
  36.      * x - The x axis on which the Tooltip will be placed. Relative to the container.
  37.      * y - The y asis on which the Tooltip will be placed. Relative to the container.
  38.      */
  39.      public Tooltip(String caption,Font tooltipFont,Container c,int x, int y)
  40.      {
  41.           super(); // Calling the parent class constructor.
  42.           containerOnWhichTheTooltipShows = c;
  43.           containerOnWhichTheTooltipShows.add(this); // Adding ourselves as a component
  44.                                                      // of the container.
  45.           this.tooltipFont = tooltipFont;
  46.           this.caption = caption;
  47.           FontMetrics fontSize = getToolkit().getFontMetrics(tooltipFont); // Checking the
  48.                                                               // size of the font.
  49.           width = fontSize.stringWidth(caption); // Computing the size of the box in which
  50.                                                  // the string
  51.           height = fontSize.getHeight();         // should be shown.
  52.           if (x < 0) x = 0; // Checking the validity of the x and y parameters.
  53.           if (y < 0) y = 0; // This should be the job of the class displaying the Tooltip,
  54.           if (x + width > containerOnWhichTheTooltipShows.getSize().width) // but we want
  55.                                            // robust code!
  56.           x = containerOnWhichTheTooltipShows.getSize().width - width;
  57.           if (y + height > containerOnWhichTheTooltipShows.getSize().height)
  58.           y = containerOnWhichTheTooltipShows.getSize().height - height;
  59.           this.x = x;
  60.           this.y = y;
  61.       }
  62.  
  63.      /**
  64.      * The dispose method removes the remains of the tooltip from the Container
  65.      * This method must be called to remove the Tooltip!
  66.      */
  67.      public void dispose()
  68.      {
  69.           containerOnWhichTheTooltipShows.remove(this); // Removing the tooltip
  70.                                                // Component from the container.
  71.           if(listOfComponentsToDrawOn != null) // If we drew on any Components
  72.                                                // other than the Container.
  73.            for (int counterOfComponentsToDrawOn = 0;
  74.                    counterOfComponentsToDrawOn < listOfComponentsToDrawOn.length;
  75.                    counterOfComponentsToDrawOn++)
  76.           {
  77.                if ((listOfComponentsToDrawOn[counterOfComponentsToDrawOn] instanceof Button) &&
  78.  
  79.                    (!(listOfComponentsToDrawOn[counterOfComponentsToDrawOn] instanceof ImageButton)))
  80.                { // This is a patch to prevent buttons from disappearing when you repaint them.
  81.                  // For some reason in windows JDK when I call repaint on a Button it vanishes.
  82.                         Button b =  (Button)
  83.                                        listOfComponentsToDrawOn[counterOfComponentsToDrawOn];
  84.                         b.setLabel(b.getLabel());
  85.                 }
  86.                else
  87.                {
  88.                    listOfComponentsToDrawOn[counterOfComponentsToDrawOn].repaint();
  89.                    listOfComponentsToDrawOn[counterOfComponentsToDrawOn].validate();
  90.                }
  91.            }
  92.      }
  93.  
  94.      public int getHeight() // This method returns the height of the Tooltip.
  95.      {
  96.           return (height);
  97.      }
  98.  
  99.      public int getWidth() // This method returns the width of the Tooltip.
  100.      {
  101.           return (width);
  102.      }
  103.  
  104.      public int getX()     // Returns the x asis of the tooltip.
  105.      {
  106.           return (x);
  107.      }
  108.  
  109.      public int getY()     // Returns the y asis of the tooltip.
  110.      {
  111.           return (y);
  112.      }
  113.  
  114.      /**
  115.      * This method draws the Tooltip on the Container and then seeks all of the
  116.      * components that overlap the Tooltip in the Container and it draws
  117.      * the parts that were cliped by that Component on every sub Component.
  118.      **/
  119.      public void paint(Graphics g)
  120.      {
  121.          // The paint is called with a clipped graphics. we draw but
  122.          // clipping will probably occure so we must fix it.
  123.          // We don't fix clipping at the end of the Container! That
  124.          // is the applications responsibility.
  125.           g.setColor(Color.black);
  126.           g.fillRect(x,  y, width + 2,height + 2);
  127.           g.setColor(Color.yellow);
  128.           g.fillRect(x + 1,y + 1,width,height);
  129.           g.setColor(Color.black);
  130.           g.setFont(tooltipFont);
  131.           g.drawString(caption,x + 1,y + height - 1);
  132.           if (containerOnWhichTheTooltipShows.getComponentCount() != 0)
  133.           { // if there are any components, check for cliping.
  134.               if(listOfComponentsToDrawOn == null)
  135.               listOfComponentsToDrawOn = getComponentsAt(x,  y, width + 2,height + 2);
  136.               if(listOfComponentsToDrawOn != null)
  137.               for (int componentIterator = 0;
  138.                   componentIterator <  listOfComponentsToDrawOn.length;
  139.                   componentIterator++)
  140.                        drawLabelOnComponent(listOfComponentsToDrawOn[componentIterator],
  141.                                             new Point(x,  y),
  142.                                             new Point(x + width + 2,y + height + 2));
  143.            }
  144.      }
  145.  
  146.      /**
  147.      * This method draws the fragment of the tooltip that shows on the Component
  148.      * on too a Component. It gets absolute postions relative to the Container and
  149.      * computes the points relative to the Container.
  150.      */
  151.      private void drawLabelOnComponent(Component c, Point topLeft, Point bottomRight)
  152.      {
  153.           // This method computes the X and Y relative to the
  154.           // Component and not the Container.
  155.           computeAbsolutePointsInComponents(c.getLocation(),topLeft, bottomRight);
  156.  
  157.           Graphics g = c.getGraphics();
  158.           if(g != null)
  159.           {
  160.               g.setColor(Color.black);
  161.               g.fillRect(topLeft.x,  topLeft.y, bottomRight.x - topLeft.x - 2,
  162.                          bottomRight.y - topLeft.y - 2);
  163.               g.setColor(Color.yellow);
  164.               g.fillRect(topLeft.x + 1,topLeft.y + 1,bottomRight.x - 3 - topLeft.x,
  165.                          bottomRight.y - 3 - topLeft.y);
  166.               g.setColor(Color.black);
  167.               g.setFont(tooltipFont);
  168.               g.drawString(caption,topLeft.x + 1,bottomRight.y - 3);
  169.           }
  170.      }
  171.  
  172.      /**
  173.      * The getComponentsAt method is called by paint and returns an array of
  174.      * Components that are overlapping the boundries given to it.
  175.      * This is used to determine on which of the Components the Tooltip should be
  176.      * drawn.
  177.      */
  178.      private Component[] getComponentsAt(int x, int y, int width, int height)
  179.      {
  180.           Component[] listOfComponents =
  181.                           containerOnWhichTheTooltipShows.getComponents();
  182.                           // Getting all of the Components in the Container.
  183.           int componentCounter = listOfComponents.length;
  184.           for (int componentIterator = 0 ; componentIterator < listOfComponents.length ;
  185.                componentIterator++)
  186.           { // Filtering out the Components that don't overlap.
  187.             if (!isClipping(listOfComponents[componentIterator],new Point(x,y),
  188.                   new Point(width + x,height + y)))
  189.             {
  190.                   listOfComponents[componentIterator] = null;
  191.                   componentCounter--;
  192.             }
  193.           }
  194.           if(componentCounter > 0) // If any Component overlaps...
  195.           {
  196.               Component[] returnValue = new Component[componentCounter];
  197.               // Allocate space for the overlaping Components.
  198.               int componentIterator = 0, secondaryComponentIterator = 0;
  199.               for (; componentIterator < listOfComponents.length ; componentIterator++)
  200.                  if(listOfComponents[componentIterator] != null)
  201.                  { // Create a new filterd list of Components.
  202.                    returnValue[secondaryComponentIterator] =
  203.                                        listOfComponents[componentIterator];
  204.                    secondaryComponentIterator++;
  205.                  }
  206.               return(returnValue);
  207.           }
  208.           else return(null);
  209.     }
  210.  
  211.      /**
  212.       * The isClipping method is used by the getComponentsAt method to determine if
  213.       * 2 Components overlap each other.
  214.       * This method returns true if the component will clip the location to bottom
  215.       * rectangle.
  216.      **/
  217.      private boolean isClipping(Component c,Point location,Point bottom)
  218.      {
  219.           Point cLocation = c.getLocation(),
  220.           cBottom = new Point(cLocation.x + c.getSize().width,
  221.                               c.getSize().height + cLocation.y),
  222.           topRight = new Point(bottom.x,location.y),
  223.           bottomLeft = new Point(location.x,bottom.y);
  224.  
  225.           return(isPointInTheMiddle(location,cLocation,cBottom)
  226.                 || isPointInTheMiddle(bottom,cLocation,cBottom)
  227.                 || isPointInTheMiddle(topRight,cLocation,cBottom)
  228.                 || isPointInTheMiddle(bottomLeft,cLocation,cBottom));
  229.      }
  230.  
  231.      /**
  232.       * This method is used by the isClipping method to determine if the point
  233.       * p is in the rectangle between points top and bottom.
  234.      **/
  235.      private static boolean isPointInTheMiddle(Point p,Point top,Point bottom)
  236.      {
  237.           return(((p.x >= top.x) && (p.x <= bottom.x) &&
  238.                   (p.y >= top.y) && (p.y <= bottom.y)));
  239.       }
  240.  
  241.      /**
  242.       * The computeAbsolutePointsInComponents method is used by the
  243.       * drawLabelOnComponent method to convert the Container based point to
  244.       * Component asis points.
  245.      **/
  246.      private void computeAbsolutePointsInComponents(Point origin, Point topLeft,
  247.                                                     Point bottomRight)
  248.      {
  249.           topLeft.x = topLeft.x - origin.x;
  250.           bottomRight.x = bottomRight.x - origin.x;
  251.           topLeft.y = topLeft.y - origin.y;
  252.           bottomRight.y = bottomRight.y - origin.y;
  253.      }
  254.  
  255.      public static int MINIMUM_SPACE_FOR_TOOLTIP = 50; // These are some
  256.                                                        // constants to help place
  257.      public static int LEFT_SPACE_FOR_TOOLTIP = 100;   // Tooltips in the
  258.                                                        // Correct position.
  259.      public static int RIGHT_SPACE_FOR_TOOLTIP = 10;
  260.      private Component[] listOfComponentsToDrawOn;     // This is the list of Components
  261.                                                        // we are drawing on.
  262.      private Container containerOnWhichTheTooltipShows;// The container on which the
  263.                                                        // Tooltip shows.
  264.      private String caption; // The text of the Tooltip.
  265.      private int x; // The tooltips x asis.
  266.      private int y; // The tooltips y asis.
  267.      private Font tooltipFont; // The tooltips Font.
  268.      private int width;  // The tooltips width.
  269.      private int height; // The tooltips height.
  270. }
  271.