Jump to content

Grinding3.java

From EDM2
Revision as of 16:28, 20 December 2017 by Ak120 (talk | contribs)
package GUITools;

import java.AWT.*;
import java.AWT.event.*;
import java.util.Vector;

/**
 * The Tooltip class was developed for use by the DockableToolbar class,
 * I chose to make it public since i feel that with slight modification
 * it can be used in other classes.
 * This class doesnt have a simple API (mostly because it was developed
 * for internal use), it has a more generic wrapper (class Hints) which I reccomend on using.
 * This class draws a yellow label tooltip (or hint/hovering help...).
 * The Tooltip class only displays a tooltip at a given X,Y location in
 * A container, if that container has Components in it that hide the tooltip
 * it will try to display on them too. The mouse functionality and the full
 * capabilities of a Tooltip are not implemented here, I will probably subclass
 * this class in a later stage to create an automatic Tooltip facility.
 * This class was developed to run under JDK 1.1.1, with very little assistance
 * from VisualAge for Java, most of the work was done using javac.
 * This class was written by Shai Almog 5/4/97. The sorce is in the public
 * domain and may be modified and used freely. It is not a requirment but
 * I would consider it good manners if you credit me and EDM/2 (www.edm2.com)
 * in applications in which this code was used ;-)
**/

public class Tooltip extends Canvas
// The reason we extend Canvas and not Component
// is due to a bug in VisualAge for Java which did not allow this.
{
     /**
     * The Tooltip constructor takes the following parameters
     * caption - the text of the tooltip.
     * tooltipFont - the font of the tooltip.
     * c - The Container on which the Tooltip will be displayed.
     * x - The x axis on which the Tooltip will be placed. Relative to the container.
     * y - The y asis on which the Tooltip will be placed. Relative to the container.
     */
     public Tooltip(String caption,Font tooltipFont,Container c,int x, int y)
     {
          super(); // Calling the parent class constructor.
          containerOnWhichTheTooltipShows = c;
          containerOnWhichTheTooltipShows.add(this); // Adding ourselves as a component
                                                     // of the container.
          this.tooltipFont = tooltipFont;
          this.caption = caption;
          FontMetrics fontSize = getToolkit().getFontMetrics(tooltipFont); // Checking the
                                                              // size of the font.
          width = fontSize.stringWidth(caption); // Computing the size of the box in which
                                                 // the string
          height = fontSize.getHeight();         // should be shown.
          if (x < 0) x = 0; // Checking the validity of the x and y parameters.
          if (y < 0) y = 0; // This should be the job of the class displaying the Tooltip,
          if (x + width > containerOnWhichTheTooltipShows.getSize().width) // but we want
                                           // robust code!
          x = containerOnWhichTheTooltipShows.getSize().width - width;
          if (y + height > containerOnWhichTheTooltipShows.getSize().height)
          y = containerOnWhichTheTooltipShows.getSize().height - height;
          this.x = x;
          this.y = y;
      }

     /**
     * The dispose method removes the remains of the tooltip from the Container
     * This method must be called to remove the Tooltip!
     */
     public void dispose()
     {
          containerOnWhichTheTooltipShows.remove(this); // Removing the tooltip
                                               // Component from the container.
          if(listOfComponentsToDrawOn != null) // If we drew on any Components
                                               // other than the Container.
           for (int counterOfComponentsToDrawOn = 0;
                   counterOfComponentsToDrawOn < listOfComponentsToDrawOn.length;
                   counterOfComponentsToDrawOn++)
          {
               if ((listOfComponentsToDrawOn[counterOfComponentsToDrawOn] instanceof Button) &&

                   (!(listOfComponentsToDrawOn[counterOfComponentsToDrawOn] instanceof ImageButton)))
               { // This is a patch to prevent buttons from disappearing when you repaint them.
                 // For some reason in windows JDK when I call repaint on a Button it vanishes.
                        Button b =  (Button)
                                       listOfComponentsToDrawOn[counterOfComponentsToDrawOn];
                        b.setLabel(b.getLabel());
                }
               else
               {
                   listOfComponentsToDrawOn[counterOfComponentsToDrawOn].repaint();
                   listOfComponentsToDrawOn[counterOfComponentsToDrawOn].validate();
               }
           }
     }

     public int getHeight() // This method returns the height of the Tooltip.
     {
          return (height);
     }

     public int getWidth() // This method returns the width of the Tooltip.
     {
          return (width);
     }

     public int getX()     // Returns the x asis of the tooltip.
     {
          return (x);
     }

     public int getY()     // Returns the y asis of the tooltip.
     {
          return (y);
     }

     /**
     * This method draws the Tooltip on the Container and then seeks all of the
     * components that overlap the Tooltip in the Container and it draws
     * the parts that were cliped by that Component on every sub Component.
     **/
     public void paint(Graphics g)
     {
         // The paint is called with a clipped graphics. we draw but
         // clipping will probably occure so we must fix it.
         // We don't fix clipping at the end of the Container! That
         // is the applications responsibility.
          g.setColor(Color.black);
          g.fillRect(x,  y, width + 2,height + 2);
          g.setColor(Color.yellow);
          g.fillRect(x + 1,y + 1,width,height);
          g.setColor(Color.black);
          g.setFont(tooltipFont);
          g.drawString(caption,x + 1,y + height - 1);
          if (containerOnWhichTheTooltipShows.getComponentCount() != 0)
          { // if there are any components, check for cliping.
              if(listOfComponentsToDrawOn == null)
              listOfComponentsToDrawOn = getComponentsAt(x,  y, width + 2,height + 2);
              if(listOfComponentsToDrawOn != null)
              for (int componentIterator = 0;
                  componentIterator <  listOfComponentsToDrawOn.length;
                  componentIterator++)
                       drawLabelOnComponent(listOfComponentsToDrawOn[componentIterator],
                                            new Point(x,  y),
                                            new Point(x + width + 2,y + height + 2));
           }
     }

     /**
     * This method draws the fragment of the tooltip that shows on the Component
     * on too a Component. It gets absolute postions relative to the Container and
     * computes the points relative to the Container.
     */
     private void drawLabelOnComponent(Component c, Point topLeft, Point bottomRight)
     {
          // This method computes the X and Y relative to the
          // Component and not the Container.
          computeAbsolutePointsInComponents(c.getLocation(),topLeft, bottomRight);

          Graphics g = c.getGraphics();
          if(g != null)
          {
              g.setColor(Color.black);
              g.fillRect(topLeft.x,  topLeft.y, bottomRight.x - topLeft.x - 2,
                         bottomRight.y - topLeft.y - 2);
              g.setColor(Color.yellow);
              g.fillRect(topLeft.x + 1,topLeft.y + 1,bottomRight.x - 3 - topLeft.x,
                         bottomRight.y - 3 - topLeft.y);
              g.setColor(Color.black);
              g.setFont(tooltipFont);
              g.drawString(caption,topLeft.x + 1,bottomRight.y - 3);
          }
     }

     /**
     * The getComponentsAt method is called by paint and returns an array of
     * Components that are overlapping the boundries given to it.
     * This is used to determine on which of the Components the Tooltip should be
     * drawn.
     */
     private Component[] getComponentsAt(int x, int y, int width, int height)
     {
          Component[] listOfComponents =
                          containerOnWhichTheTooltipShows.getComponents();
                          // Getting all of the Components in the Container.
          int componentCounter = listOfComponents.length;
          for (int componentIterator = 0 ; componentIterator < listOfComponents.length ;
               componentIterator++)
          { // Filtering out the Components that don't overlap.
            if (!isClipping(listOfComponents[componentIterator],new Point(x,y),
                  new Point(width + x,height + y)))
            {
                  listOfComponents[componentIterator] = null;
                  componentCounter--;
            }
          }
          if(componentCounter > 0) // If any Component overlaps...
          {
              Component[] returnValue = new Component[componentCounter];
              // Allocate space for the overlaping Components.
              int componentIterator = 0, secondaryComponentIterator = 0;
              for (; componentIterator < listOfComponents.length ; componentIterator++)
                 if(listOfComponents[componentIterator] != null)
                 { // Create a new filterd list of Components.
                   returnValue[secondaryComponentIterator] =
                                       listOfComponents[componentIterator];
                   secondaryComponentIterator++;
                 }
              return(returnValue);
          }
          else return(null);
    }

     /**
      * The isClipping method is used by the getComponentsAt method to determine if
      * 2 Components overlap each other.
      * This method returns true if the component will clip the location to bottom
      * rectangle.
     **/
     private boolean isClipping(Component c,Point location,Point bottom)
     {
          Point cLocation = c.getLocation(),
          cBottom = new Point(cLocation.x + c.getSize().width,
                              c.getSize().height + cLocation.y),
          topRight = new Point(bottom.x,location.y),
          bottomLeft = new Point(location.x,bottom.y);

          return(isPointInTheMiddle(location,cLocation,cBottom)
                || isPointInTheMiddle(bottom,cLocation,cBottom)
                || isPointInTheMiddle(topRight,cLocation,cBottom)
                || isPointInTheMiddle(bottomLeft,cLocation,cBottom));
     }

     /**
      * This method is used by the isClipping method to determine if the point
      * p is in the rectangle between points top and bottom.
     **/
     private static boolean isPointInTheMiddle(Point p,Point top,Point bottom)
     {
          return(((p.x >= top.x) && (p.x <= bottom.x) &&
                  (p.y >= top.y) && (p.y <= bottom.y)));
      }

     /**
      * The computeAbsolutePointsInComponents method is used by the
      * drawLabelOnComponent method to convert the Container based point to
      * Component asis points.
     **/
     private void computeAbsolutePointsInComponents(Point origin, Point topLeft,
                                                    Point bottomRight)
     {
          topLeft.x = topLeft.x - origin.x;
          bottomRight.x = bottomRight.x - origin.x;
          topLeft.y = topLeft.y - origin.y;
          bottomRight.y = bottomRight.y - origin.y;
     }

     public static int MINIMUM_SPACE_FOR_TOOLTIP = 50; // These are some
                                                       // constants to help place
     public static int LEFT_SPACE_FOR_TOOLTIP = 100;   // Tooltips in the
                                                       // Correct position.
     public static int RIGHT_SPACE_FOR_TOOLTIP = 10;
     private Component[] listOfComponentsToDrawOn;     // This is the list of Components
                                                       // we are drawing on.
     private Container containerOnWhichTheTooltipShows;// The container on which the
                                                       // Tooltip shows.
     private String caption; // The text of the Tooltip.
     private int x; // The tooltips x asis.
     private int y; // The tooltips y asis.
     private Font tooltipFont; // The tooltips Font.
     private int width;  // The tooltips width.
     private int height; // The tooltips height.
}