home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / Source.bin / DirectionButton.java < prev    next >
Text File  |  1998-03-18  |  24KB  |  774 lines

  1. package symantec.itools.awt;
  2.  
  3. import java.awt.Rectangle;
  4. import java.awt.Dimension;
  5. import java.awt.Color;
  6. import java.awt.Graphics;
  7. import java.beans.PropertyVetoException;
  8. import java.beans.PropertyChangeListener;
  9. import java.beans.VetoableChangeListener;
  10. import java.beans.PropertyChangeEvent;
  11. import java.lang.IllegalArgumentException;
  12. import symantec.itools.awt.util.ColorUtils;
  13. import java.util.ResourceBundle;
  14.  
  15. //    01/29/97    TWB    Integrated changes from Windows
  16. //    05/23/97    LAB    Updated to support Java 1.1
  17. //    06/27/97    LAB    Changed the way the button is drawn.  Now it uses the offscreen
  18. //                    Image.  Cleaned up the drawing code to be more universal.
  19. //                    Added the ArrowColor property to allow the arrow to have a
  20. //                    user definable color.  The disabled color is derived from this color.
  21. //    07/02/97    LAB    Constrained the Arrow Indent Property, so the arrow wouldn't draw strangely
  22. //                    if the inset was set to a large value.
  23. //    07/08/97    LAB    Changed the preferedSize() method to return a button whose arrow is 20 by 20.
  24. //    07/13/97    RKM    Fixed misspelling of prefered
  25. //    07/19/97    LAB    Replaced updatePolygon with fillTriangle and changed the drawing method from
  26. //                    using a polygon to using lines because polygons were problematic.  Changed
  27. //                    getPreferredSize to return the smallest size which the button looks good and
  28. //                    changed getMinimumSize to return the smallest possible size for the button and
  29. //                    still be recognized as a DirectionButton.
  30. //  07/25/97    CAR marked fields transient as needed
  31. //                  innerclasses implement java.io.Serializable
  32. //    10/05/97    LAB    Changed names of strings in PropertyChangeEvent handling to follow Bean Spec
  33. //                    naming conventions.  Added mechanism for internally constrained properties
  34. //                    to be validated after the component is added to the form to avoid code-gen
  35. //                    order specific dependencies.
  36. //    10/06/97    LAB    Initialized tempIndent to indent which resolves shrinkTriangle
  37. //                    and setArrowIndent conflicts (Addresses Mac Bug #9014).  Changed
  38. //                    addNotify to call it's super after listeners are hooked up so
  39. //                    verifyContstrainedPropertyValues will be called after the listeners
  40. //                    are hooked up.  Changed setArrowIndent to set the temp value to the
  41. //                    current value when changing the current value.  Changed
  42. //                    getBevelHeight to return the temp value if the component is not
  43. //                    added.  This fixes a problem at design time where the component would
  44. //                    revert to it's default state after a back run
  45.  
  46. /**
  47.  * The DirectionButton is a button component that has an arrow drawn in it that
  48.  * points one of four ways (left, up, right, or down). At runtime, the button has
  49.  * a raised look and a pressed look.
  50.  * <p>
  51.  * This component is usually used in conjunction with a combo or list box to
  52.  * indicate a list that the user can view by clicking the arrow, or with spinners
  53.  * to let the user scroll through available values.
  54.  * <p>
  55.  * @version 1.1, June 27, 1997
  56.  * @author  Symantec
  57.  */
  58. public class DirectionButton extends ButtonBase implements java.io.Serializable
  59. {
  60.     /**
  61.      * The point LEFT style constant.
  62.      */
  63.     public static final int LEFT = 0;
  64.  
  65.     /**
  66.      * The point RIGHT style constant.
  67.      */
  68.     public static final int RIGHT = 1;
  69.  
  70.     /**
  71.      * The point UP style constant.
  72.      */
  73.     public static final int UP = 2;
  74.  
  75.     /**
  76.      * The point DOWN style constant.
  77.      */
  78.     public static final int DOWN = 3;
  79.  
  80.     /**
  81.      * Constructs a default DirectionButton, which will point left.
  82.      */
  83.     public DirectionButton()
  84.     {
  85.         this(LEFT);
  86.     }
  87.  
  88.     /**
  89.      * Constructs a DirectionButton pointing the specified direction.
  90.      * @param d a style constant indicating which direction to point the button
  91.      * @see #LEFT
  92.      * @see #UP
  93.      * @see #RIGHT
  94.      * @see #DOWN
  95.      */
  96.     public DirectionButton(int d)
  97.     {
  98.         direction     = d;
  99.         left         = 0;
  100.         right        = 0;
  101.         bottom        = 0;
  102.         indent        = 0;
  103.         tempIndent    = indent;
  104.         try { setArrowColor(Color.black); } catch (PropertyVetoException exc) {}
  105.  
  106.     }
  107.  
  108.     /**
  109.      * Sets the direction of the arrow after construction.
  110.      * @param d constant indicating direction to point button
  111.      * @exception PropertyVetoException
  112.      * if the specified property value is unacceptable
  113.      * @see #getDirection
  114.      * @see #LEFT
  115.      * @see #UP
  116.      * @see #RIGHT
  117.      * @see #DOWN
  118.      */
  119.     public void setDirection(int d) throws PropertyVetoException
  120.     {
  121.         if(direction != d)
  122.         {
  123.             Integer oldValue = new Integer(direction);
  124.             Integer newValue = new Integer(d);
  125.  
  126.             vetos.fireVetoableChange("direction", oldValue, newValue);
  127.  
  128.             direction = d;
  129.             repaint();
  130.  
  131.             changes.firePropertyChange("direction", oldValue, newValue);
  132.         }
  133.     }
  134.  
  135.     /**
  136.      * Returns the direction the button is currently pointing.
  137.      * @see #setDirection
  138.      * @see #LEFT
  139.      * @see #UP
  140.      * @see #RIGHT
  141.      * @see #DOWN
  142.      */
  143.     public int getDirection()
  144.     {
  145.         return direction;
  146.     }
  147.  
  148.     /**
  149.      * Sets the amount of blank space between the arrow and the button
  150.      * border in pixels.
  151.      * @param ai the margin around the arrow in pixels. 0=arrow takes up entire button
  152.      * @exception PropertyVetoException
  153.      * if the specified property value is unacceptable
  154.      * @see #getArrowIndent
  155.      */
  156.     public void setArrowIndent(int ai) throws PropertyVetoException
  157.     {
  158.         if(isAdded)
  159.         {
  160.             if(indent != ai)
  161.             {
  162.                 Integer oldValue = new Integer(indent);
  163.                 Integer newValue = new Integer(ai);
  164.  
  165.                 vetos.fireVetoableChange("arrowIndent", oldValue, newValue);
  166.  
  167.                 indent = ai;
  168.                 tempIndent = ai;
  169.                 //Make sure that changes to indent don't make changes to shrinkTriangle
  170.                 //give us a bad triangle.
  171.                 shrinkTriangle(left, right, top, bottom);
  172.                 repaint();
  173.  
  174.                 changes.firePropertyChange("arrowIndent", oldValue, newValue);
  175.             }
  176.         }
  177.         //We store the value until we are added then set the value to avoid code-gen order dependencies.
  178.         else
  179.         {
  180.             tempIndent = ai;
  181.         }
  182.     }
  183.  
  184.     /**
  185.      * Sets the color of the direction arrow.
  186.      * @param newValue the new arrow color.
  187.      * @exception PropertyVetoException
  188.      * if the specified property value is unacceptable
  189.      * @see #getArrowColor
  190.      */
  191.     public void setArrowColor(Color newValue) throws PropertyVetoException
  192.     {
  193.         if (!symantec.itools.util.GeneralUtils.objectsEqual(arrowColor, newValue))
  194.         {
  195.             Color oldValue = arrowColor;
  196.  
  197.             vetos.fireVetoableChange("arrowColor", oldValue, newValue);
  198.  
  199.             arrowColor = newValue;
  200.             try
  201.             {
  202.                 disabledArrowColor = ColorUtils.fade(arrowColor, Color.lightGray, 0.50);
  203.             }
  204.             catch (IllegalArgumentException exc) {}
  205.  
  206.             repaint();
  207.  
  208.             changes.firePropertyChange("arrowColor", oldValue, newValue);
  209.         }
  210.     }
  211.  
  212.     /**
  213.      * Gets the current color of the direction arrow.
  214.      * @return the current arrow color
  215.      * @see #setArrowColor
  216.      */
  217.     public Color getArrowColor()
  218.     {
  219.         return arrowColor;
  220.     }
  221.  
  222.     /**
  223.      * Returns the amount of blank space between the arrow and the button
  224.      * border in pixels.
  225.      * @see #setArrowIndent
  226.      */
  227.     public int getArrowIndent()
  228.     {
  229.         return isAdded ? indent : tempIndent;
  230.     }
  231.  
  232.     /**
  233.      * Sets the extra amount, in pixels, to shrink the arrow triangle.
  234.      * Constrains the values such that the arrow will never be less than
  235.      * three pixels.  If a value is entered that would exceed this limit,
  236.      * the limit will be used instead.
  237.      * @param left pixels to shrink from left side
  238.      * @param right pixels to shrink from right side
  239.      * @param top pixels to shrink from top
  240.      * @param bottom pixels to shrink from bottom
  241.      */
  242.     public void shrinkTriangle(int l, int r, int t, int b)
  243.     {
  244.         if(isAdded)
  245.         {
  246.             Dimension s = getSize();
  247.             int maxWidth    = s.width - bevel - bevel - 2;
  248.             int maxHeight    = s.height - bevel - bevel - 2;
  249.  
  250.             if(maxWidth - (l + r + indent + indent) >= 3)
  251.             {
  252.                 left    = l;
  253.                 right    = r;
  254.             }
  255.             else
  256.             {
  257.                 left    = (maxWidth - indent - indent - 3) / 2;
  258.                 right    = left;
  259.             }
  260.  
  261.             if(maxHeight - (t + b + indent + indent) >= 3)
  262.             {
  263.                 top        = t;
  264.                 bottom    = b;
  265.             }
  266.             else
  267.             {
  268.                 top    = (maxHeight - indent - indent - 3) / 2;
  269.                 bottom    = top;
  270.             }
  271.         }
  272.     }
  273.  
  274.     /**
  275.      * Returns the recommended dimensions to properly display this component.
  276.      * This is a standard Java AWT method which gets called to determine
  277.      * the recommended size of this component.
  278.      *
  279.      * @return a button that has a content area of 7 by 7 pixels.
  280.      * @see java.awt.Component#getMinimumSize
  281.      */
  282.     public Dimension getPreferredSize()
  283.     {
  284.         Dimension defaultSize = super.getPreferredSize();
  285.  
  286.         return new Dimension(defaultSize.width + 7, defaultSize.height + 7);
  287.     }
  288.  
  289.     /**
  290.      * Returns the minimum dimensions to properly display this component.
  291.      * This is a standard Java AWT method which gets called to determine
  292.      * the minimum size of this component.
  293.      *
  294.      * @return a button that has a content area of 3 by 3 pixels.
  295.      * @see java.awt.Component#getMinimumSize
  296.      */
  297.     public Dimension getMinimumSize()
  298.     {
  299.         Dimension defaultSize = super.getPreferredSize();
  300.  
  301.         return new Dimension(defaultSize.width + 3, defaultSize.height + 3);
  302.     }
  303.  
  304.     /**
  305.      * Tells this component that it has been added to a container.
  306.      * This is a standard Java AWT method which gets called by the AWT when
  307.      * this component is added to a container. Typically, it is used to
  308.      * create this component's peer.
  309.      *
  310.      * It has been overridden here to hook-up event listeners.
  311.      *
  312.      * @see #removeNotify
  313.      */
  314.     public synchronized void addNotify()
  315.     {
  316.         errors = ResourceBundle.getBundle("symantec.itools.resources.ErrorsBundle");
  317.  
  318.         //Hook up listeners
  319.         if (sizeVeto == null)
  320.         {
  321.             sizeVeto = new SizeVeto();
  322.             addDirectionListener(sizeVeto);
  323.         }
  324.         if (indentVeto == null)
  325.         {
  326.             indentVeto = new IndntVeto();
  327.             addArrowIndentListener(indentVeto);
  328.         }
  329.  
  330.         //Add after the listeners are hooked up
  331.         super.addNotify();
  332.     }
  333.  
  334.     /**
  335.      * Tells this component that it is being removed from a container.
  336.      * This is a standard Java AWT method which gets called by the AWT when
  337.      * this component is removed from a container. Typically, it is used to
  338.      * destroy the peers of this component and all its subcomponents.
  339.      *
  340.      * It has been overridden here to unhook event listeners.
  341.      *
  342.      * @see #addNotify
  343.      */
  344.     public synchronized void removeNotify()
  345.     {
  346.         //Unhook listeners
  347.         if (sizeVeto != null)
  348.         {
  349.             removeDirectionListener(sizeVeto);
  350.             sizeVeto = null;
  351.         }
  352.         if (indentVeto != null)
  353.         {
  354.             removeArrowIndentListener(indentVeto);
  355.             indentVeto = null;
  356.         }
  357.  
  358.         super.removeNotify();
  359.     }
  360.  
  361.     /**
  362.      * Adds a listener for all event changes.
  363.      * @param listener the listener to add.
  364.      * @see #removePropertyChangeListener
  365.      */
  366.     public synchronized void addPropertyChangeListener(PropertyChangeListener listener)
  367.     {
  368.         super.addPropertyChangeListener(listener);
  369.         changes.addPropertyChangeListener(listener);
  370.     }
  371.  
  372.     /**
  373.      * Removes a listener for all event changes.
  374.      * @param listener the listener to remove.
  375.      * @see #addPropertyChangeListener
  376.      */
  377.     public synchronized void removePropertyChangeListener(PropertyChangeListener listener)
  378.     {
  379.         super.removePropertyChangeListener(listener);
  380.         changes.removePropertyChangeListener(listener);
  381.     }
  382.  
  383.     /**
  384.      * Adds a vetoable listener for all event changes.
  385.      * @param listener the listener to add.
  386.      * @see #removeVetoableChangeListener
  387.      */
  388.     public synchronized void addVetoableChangeListener(VetoableChangeListener listener)
  389.     {
  390.          super.addVetoableChangeListener(listener);
  391.         vetos.addVetoableChangeListener(listener);
  392.     }
  393.  
  394.     /**
  395.      * Removes a vetoable listener for all event changes.
  396.      * @param listener the listener to remove.
  397.      * @see #addVetoableChangeListener
  398.      */
  399.     public synchronized void removeVetoableChangeListener(VetoableChangeListener listener)
  400.     {
  401.         super.removeVetoableChangeListener(listener);
  402.         vetos.removeVetoableChangeListener(listener);
  403.     }
  404.  
  405.     /**
  406.      * Adds a listener for the Direction property changes.
  407.      * @param listener the listener to add.
  408.      * @see #removeDirectionListener
  409.      */
  410.     public synchronized void addDirectionListener(PropertyChangeListener listener)
  411.     {
  412.         changes.addPropertyChangeListener("direction", listener);
  413.     }
  414.  
  415.     /**
  416.      * Removes a listener for the Direction property changes.
  417.      * @param listener the listener to remove.
  418.      * @see #addDirectionListener
  419.      */
  420.     public synchronized void removeDirectionListener(PropertyChangeListener listener)
  421.     {
  422.         changes.removePropertyChangeListener("direction", listener);
  423.     }
  424.  
  425.     /**
  426.      * Adds a vetoable listener for the Direction property changes.
  427.      * @param listener the listener to add.
  428.      * @see #removeDirectionListener
  429.      */
  430.     public synchronized void addDirectionListener(VetoableChangeListener listener)
  431.     {
  432.         vetos.addVetoableChangeListener("direction", listener);
  433.     }
  434.  
  435.     /**
  436.      * Removes a vetoable listener for the Direction property changes.
  437.      * @param listener the listener to remove.
  438.      * @see #addDirectionListener
  439.      */
  440.     public synchronized void removeDirectionListener(VetoableChangeListener listener)
  441.     {
  442.         vetos.removeVetoableChangeListener("direction", listener);
  443.     }
  444.  
  445.     /**
  446.      * Adds a listener for the ArrowIndent property changes.
  447.      * @param listener the listener to add.
  448.      * @see #removeArrowIndentListener
  449.      */
  450.     public synchronized void addArrowIndentListener(PropertyChangeListener listener)
  451.     {
  452.         changes.addPropertyChangeListener("arrowIndent", listener);
  453.     }
  454.  
  455.     /**
  456.      * Removes a listener for the ArrowIndent property changes.
  457.      * @param listener the listener to remove.
  458.      * @see #addArrowIndentListener
  459.      */
  460.     public synchronized void removeArrowIndentListener(PropertyChangeListener listener)
  461.     {
  462.         changes.removePropertyChangeListener("arrowIndent", listener);
  463.     }
  464.  
  465.     /**
  466.      * Adds a vetoable listener for the ArrowIndent property changes.
  467.      * @param listener the listener to add.
  468.      * @see #removeArrowIndentListener
  469.      */
  470.     public synchronized void addArrowIndentListener(VetoableChangeListener listener)
  471.     {
  472.         vetos.addVetoableChangeListener("arrowIndent", listener);
  473.     }
  474.  
  475.     /**
  476.      * Removes a vetoable listener for the ArrowIndent property changes.
  477.      * @param listener the listener to remove.
  478.      * @see #addArrowIndentListener
  479.      */
  480.     public synchronized void removeArrowIndentListener(VetoableChangeListener listener)
  481.     {
  482.         vetos.removeVetoableChangeListener("arrowIndent", listener);
  483.     }
  484.  
  485.     /**
  486.      * This is the PropertyChangeEvent handling inner class for the constrained Direction property.
  487.      * Handles vetoing Directions that are not valid.
  488.      */
  489.     class SizeVeto implements java.beans.VetoableChangeListener, java.io.Serializable
  490.     {
  491.         /**
  492.          * This method gets called when an attempt to change the constrained Direction property is made.
  493.          * Ensures the given direction size is valid for this button.
  494.          *
  495.          * @param     e a <code>PropertyChangeEvent</code> object describing the
  496.          *             event source and the property that has changed.
  497.          * @exception PropertyVetoException if the recipient wishes the property
  498.          *              change to be rolled back.
  499.          */
  500.         public void vetoableChange(PropertyChangeEvent e) throws PropertyVetoException
  501.         {
  502.             int i = ((Integer)e.getNewValue()).intValue();
  503.             if (!isValidDirection(i))
  504.             {
  505.                 throw new PropertyVetoException(errors.getString("InvalidDirection") + i, e);
  506.             }
  507.         }
  508.     }
  509.  
  510.     /**
  511.      * This is the PropertyChangeEvent handling inner class for the constrained ArrowIndent property.
  512.      * Handles vetoing ArrowIndents that are not valid.
  513.      */
  514.     class IndntVeto implements java.beans.VetoableChangeListener, java.io.Serializable
  515.     {
  516.         /**
  517.          * This method gets called when an attempt to change the constrained ArrowIndent property is made.
  518.          * Ensures the given arrow indent size is valid for this button.
  519.          *
  520.          * @param     e a <code>PropertyChangeEvent</code> object describing the
  521.          *             event source and the property that has changed.
  522.          * @exception PropertyVetoException if the recipient wishes the property
  523.          *              change to be rolled back.
  524.          */
  525.         public void vetoableChange(PropertyChangeEvent e) throws PropertyVetoException
  526.         {
  527.             int i = ((Integer)e.getNewValue()).intValue();
  528.             if (!isValidArrowIndent(i))
  529.             {
  530.                 throw new PropertyVetoException(errors.getString("InvalidArrowIndent") + i, e);
  531.             }
  532.         }
  533.     }
  534.  
  535.  
  536.     /**
  537.      * Maintains the buttonImage size and draws the
  538.      * button in the buttonImage offscreen image.
  539.      * @see symantec.itools.awt.ButtonBase#updateButtonImage
  540.      */
  541.     protected void updateButtonImage()
  542.     {
  543.         super.updateButtonImage();
  544.         Graphics g        = buttonImage.getGraphics();
  545.         Dimension s        = size();;
  546.         int trueBevel    = bevel + 1;
  547.         int centerHorizontal;
  548.         int centerVertical;
  549.         int topSide;
  550.         int bottomSide;
  551.         int leftSide;
  552.         int rightSide;
  553.  
  554.         if(isEnabled())
  555.         {
  556.             g.setColor(arrowColor);
  557.         }
  558.         else
  559.         {
  560.             g.setColor(disabledArrowColor);
  561.         }
  562.  
  563.         centerHorizontal    = ((s.width - 1) / 2)                    + pressedAdjustment;
  564.         centerVertical        = ((s.height - 1) / 2)                    + pressedAdjustment;
  565.         topSide                = (top + trueBevel - 1)                    + pressedAdjustment  + indent;
  566.         bottomSide            = (s.height - 1 - bottom - trueBevel)    + pressedAdjustment  - indent;
  567.         leftSide            = (left + trueBevel - 1)                + pressedAdjustment  + indent;
  568.         rightSide            = (s.width - 1 - right - trueBevel)        + pressedAdjustment  - indent;
  569.  
  570.         if (symantec.itools.lang.OS.isMacintosh())
  571.         {
  572.             leftSide    += 1;
  573.             topSide        += 1;
  574.         }
  575.  
  576.         switch (direction)
  577.         {
  578.             case UP:
  579.             {
  580.                 fillTriangle(g, centerHorizontal, topSide, leftSide, bottomSide, rightSide, bottomSide, direction);
  581.                 break;
  582.             }
  583.             case DOWN:
  584.             {
  585.                 fillTriangle(g, centerHorizontal, bottomSide, leftSide, topSide, rightSide, topSide, direction);
  586.                 break;
  587.             }
  588.  
  589.             case LEFT:
  590.             {
  591.                 fillTriangle(g, leftSide, centerVertical, rightSide, bottomSide, rightSide, topSide, direction);
  592.                 break;
  593.             }
  594.  
  595.             case RIGHT:
  596.             {
  597.                 fillTriangle(g, rightSide, centerVertical, leftSide, bottomSide, leftSide, topSide, direction);
  598.                 break;
  599.             }
  600.         }
  601.         if (g != null)
  602.             g.dispose();
  603.     }
  604.  
  605.     /**
  606.      * Fills a triangle which has at least one side that is straight up and down or left and right.
  607.      * @param g the Graphics to use to draw with.
  608.      * @param tipX the horizontal coordinate of the point opposite a straight side.
  609.      * @param tipY the vertical coordinate of the point opposite a straight side.
  610.      * @param aX the horizontal coordinate of one of the two points defining the straight side.
  611.      * @param aY the vertical coordinate of one of the two points defining the straight side.
  612.      * @param bX the horizontal coordinate of one of the two points defining the straight side.
  613.      * @param bY the vertical coordinate of one of the two points defining the straight side.
  614.      * @param direction the direction of the straight line UP, DOWN, or LEFT, RIGHT.
  615.      *
  616.      * aX and bX should be the same for UP or Down.  aY and bY should be the same for LEFT or RIGHT.
  617.      * If not, then the a coordinates are used.
  618.      *
  619.      * @see #UP
  620.      * @see #DOWN
  621.      * @see #LEFT
  622.      * @see #RIGHT
  623.      */
  624.     protected void fillTriangle(Graphics g, int tipX, int tipY, int aX, int aY, int bX, int bY, int direction)
  625.     {
  626.         int dist, max, min;
  627.  
  628.         switch(direction)
  629.         {
  630.             case UP:
  631.             case DOWN:
  632.                 dist = Math.abs(aX - bX);
  633.                 max = Math.max(aX, bX);
  634.                 min = Math.min(aX, bX);
  635.                 for(int i = min; i <= max; ++i)
  636.                 {
  637.                     g.drawLine(tipX, tipY, i, aY);
  638.                 }
  639.                 break;
  640.             case RIGHT:
  641.             case LEFT:
  642.                 dist = Math.abs(aY - bY);
  643.                 max = Math.max(aY, bY);
  644.                 min = Math.min(aY, bY);
  645.                 for(int i = min; i <= max; ++i)
  646.                 {
  647.                     g.drawLine(tipX, tipY, aX, i);
  648.                 }
  649.                 break;
  650.         }
  651.     }
  652.  
  653.     /**
  654.      * Is the given bevel size valid for this button.
  655.      * @param i the given bevel size
  656.      * @return true if the given bevel size is acceptable, false if not.
  657.      */
  658.     protected boolean isValidBevelSize(int i)
  659.     {
  660.         Dimension s = size();
  661.  
  662.         int temp = i * 2 + 4;
  663.  
  664.         if (i < 0 || s.width < temp || s.height < temp)
  665.             return false;
  666.         else
  667.             return true;
  668.     }
  669.  
  670.     /**
  671.      * Is the given direction valid for this button.
  672.      * @param i the given bevel size
  673.      * @return true if the given direction is acceptable, false if not.
  674.      */
  675.     protected boolean isValidDirection(int i)
  676.     {
  677.         switch(i)
  678.         {
  679.             case LEFT:
  680.             case RIGHT:
  681.             case UP:
  682.             case DOWN:
  683.                 return true;
  684.             default:
  685.                 return false;
  686.         }
  687.     }
  688.  
  689.     /**
  690.      * Is the given arrow indent is valid for this button.
  691.      * @param i the given bevel size
  692.      * @return true if the given indent size is acceptable, false if not.
  693.      */
  694.     protected boolean isValidArrowIndent(int i)
  695.     {
  696.         Dimension s = size();
  697.  
  698.         int temp = (i * 2) + (bevel + 1) * 2 + 4;
  699.  
  700.         if(i < 0 || s.width < temp || s.height < temp)
  701.             return false;
  702.         else
  703.             return true;
  704.     }
  705.  
  706.     /**
  707.      * Called after addNotify to set the internally constrined properties to their
  708.      * temporary values to validate them now that the component has been added to the form.
  709.      * This is used to avoid code-gen order dependencies, since VC generates all property
  710.      * manipulating code before adding the component to its container.
  711.      * Subclasses should override this function for any internally constrained properties,
  712.      * and call the super version in the overridden version.
  713.      */
  714.     protected void verifyContstrainedPropertyValues()
  715.     {
  716.         super.verifyContstrainedPropertyValues();
  717.         try { setArrowIndent(tempIndent); } catch (PropertyVetoException exc) { /*Silently verify.*/ }
  718.     }
  719.  
  720.     /**
  721.      * The color of the arrow in the button.
  722.      */
  723.     protected Color    arrowColor            = null;
  724.     /**
  725.      * The color of the arrow when the button is disabled.
  726.      */
  727.     protected Color    disabledArrowColor    = null;
  728.     /**
  729.      * The direction the arrow points.
  730.      * One of: LEFT, UP, RIGHT, or DOWN.
  731.      * @see #LEFT
  732.      * @see #UP
  733.      * @see #RIGHT
  734.      * @see #DOWN
  735.      */
  736.     protected int        direction;
  737.     /**
  738.      * The number of pixels to shrink the arrow from the left side of the button.
  739.      */
  740.     protected int        left;
  741.     /**
  742.      * The number of pixels to shrink the arrow from the right side of the button.
  743.      */
  744.     protected int        right;
  745.     /**
  746.      * The number of pixels to shrink the arrow from the top side of the button.
  747.      */
  748.     protected int        top;
  749.     /**
  750.      * The number of pixels to shrink the arrow from the bottom side of the button.
  751.      */
  752.     protected int        bottom;
  753.     /**
  754.      * The margin around the arrow in pixels. 0 = arrow takes up entire button.
  755.      */
  756.     protected int        indent;
  757.     /**
  758.      * Internal use.
  759.      * Indent value stored until this component is added to a container.
  760.      * It is then used to set the real indent value.
  761.      * This avoids code-gen order dependencies.
  762.      */
  763.     protected int        tempIndent;
  764.     /**
  765.      * Error strings.
  766.      */
  767.     transient protected ResourceBundle errors;
  768.  
  769.     private SizeVeto    sizeVeto    = null;
  770.     private IndntVeto    indentVeto    = null;
  771.     private symantec.itools.beans.VetoableChangeSupport vetos = new symantec.itools.beans.VetoableChangeSupport(this);
  772.     private symantec.itools.beans.PropertyChangeSupport changes = new symantec.itools.beans.PropertyChangeSupport(this);
  773. }
  774.