home *** CD-ROM | disk | FTP | other *** search
/ Symantec Visual Cafe for Java 2.5 / symantec-visual-cafe-2.5-database-dev-edition.iso / Visual Cafe Pro v1.0 / SOURCE.BIN / VerticalSlider.java < prev    next >
Encoding:
Java Source  |  1997-06-19  |  12.4 KB  |  492 lines

  1. package symantec.itools.awt;
  2.  
  3.  
  4. import java.awt.Event;
  5. import java.awt.Graphics;
  6. import java.awt.Color;
  7.  
  8.  
  9. /**
  10.  * A VerticalSlider component. This component is used to select one value
  11.  * from a continuous range of values. It has a movable thumb in front of a 
  12.  * gauge with ticks marks on it.
  13.  * <p>
  14.  * @see symantec.itools.awt.Slider
  15.  * @see symantec.itools.awt.HorizontalSlider
  16.  * @version 1.0, Nov 26, 1996
  17.  * @author Symantec
  18.  */
  19.  
  20. //     02/15/97    RKM    Added validate - Fixes problem where calls to setMinValue & setMaxValue
  21. //                    would not work if called after reshape
  22. //     02/27/97    RKM    Integrated Scott's change to use the background color of the component
  23.  
  24. public class VerticalSlider
  25.     extends Slider
  26. {
  27.     private static final int BORDER_X       = 10;
  28.     private static final int BORDER_Y       = 15;
  29.     /**
  30.      * Length of the gauge ticks in pixels.
  31.      */
  32.     protected static final int TICK_WIDTH   = 4;
  33.  
  34.     private VerticalSliderTick tick[];
  35.     private VerticalSliderThumb thumb;
  36.  
  37.     /**
  38.      * Constructs a default VerticalSlider.
  39.      */
  40.     /**
  41.      * Constructs a default VerticalSlider. The ticks
  42.      * are drawn on both sides of the gauge with a frequency of 1. 
  43.      * The minimum value is 1. The maximum value is 10. The
  44.      * border is shown.
  45.      */
  46.     public VerticalSlider()
  47.     {
  48.         this.thumb       = new VerticalSliderThumbBoth();
  49.         this.style       = TICK_BOTH;
  50.         this.min         = 1;
  51.         this.max         = 10;
  52.         this.freq        = 1;
  53.  
  54.         prevPos          =
  55.         curPos           = 0;
  56.  
  57.         width            = 175;
  58.         height           = 50;
  59.  
  60.         showBorder       = true;
  61.  
  62.         tick             = null;
  63.     }
  64.  
  65.     /**
  66.      * Sets the current slider tick mark style.
  67.      * @see #getTickStyle
  68.      * @see Slider#TICK_LEFT
  69.      * @see Slider#TICK_RIGHT
  70.      * @see Slider#TICK_BOTH
  71.      */
  72.     public void setTickStyle(int style)
  73.     {
  74.         if (this.style != style)
  75.         {
  76.             this.style = style;
  77.     
  78.             switch (style)
  79.             {
  80.                 case TICK_LEFT :
  81.                     thumb = new VerticalSliderThumbLeft();
  82.                     break;
  83.     
  84.                 case TICK_RIGHT :
  85.                     thumb = new VerticalSliderThumbRight();
  86.                     break;
  87.     
  88.                 default :
  89.                     thumb = new VerticalSliderThumbBoth();
  90.                     break;
  91.             }
  92.             
  93.             invalidate();
  94.         }
  95.     }
  96.  
  97.     /**
  98.      * Returns the current slider tick mark style.
  99.      * @see #setTickStyle
  100.      * @see Slider#TICK_LEFT
  101.      * @see Slider#TICK_RIGHT
  102.      * @see Slider#TICK_BOTH
  103.      */
  104.     public int getTickStyle()
  105.     {
  106.         return style;
  107.     }
  108.  
  109.     /**
  110.      * Processes MOUSE_DOWN events.
  111.      * This is a standard Java AWT method which gets called by the AWT
  112.      * method handleEvent() in response to receiving a MOUSE_DOWN
  113.      * event. These events occur when the mouse button is pressed while
  114.      * inside this component.
  115.      *
  116.      * @param e the event
  117.      * @param x the component-relative horizontal coordinate of the mouse
  118.      * @param y the component-relative vertical coordinate of the mouse
  119.      *
  120.      * @return always true since the event was handled
  121.      *
  122.      * @see java.awt.Component#mouseUp
  123.      * @see java.awt.Component#handleEvent
  124.      */
  125.     public boolean mouseDown(Event e, int x, int y)
  126.     {
  127.         moveThumb(y, true);
  128.  
  129.         return true;
  130.     }
  131.  
  132.     /**
  133.      * Processes MOUSE_DRAG events.
  134.      * This is a standard Java AWT method which gets called by the AWT
  135.      * method handleEvent() in response to receiving a MOUSE_DRAG
  136.      * event. These events occur when the mouse is moved around inside this
  137.      * component while the button is pressed.
  138.      *
  139.      * @param e the event
  140.      * @param x the component-relative horizontal coordinate of the mouse
  141.      * @param y the component-relative vertical coordinate of the mouse
  142.      *
  143.      * @return always true since the event was handled
  144.      *
  145.      * @see java.awt.Component#mouseMove
  146.      * @see java.awt.Component#handleEvent
  147.      */
  148.     public boolean mouseDrag(Event e, int x, int y)
  149.     {
  150.         moveThumb(y, false);
  151.  
  152.         return true;
  153.     }
  154.  
  155.     private void do_reshape(int w, int h)
  156.     {
  157.         int hb = BORDER_X;
  158.         int vb = BORDER_Y;
  159.  
  160.         if (w < hb)
  161.             hb = w / 4;
  162.  
  163.         if (h < vb)
  164.             vb = h / 4;
  165.  
  166.         int x0 = hb;
  167.         int x1 = w - hb;
  168.         int y0 = vb;
  169.         int y1 = h - vb;
  170.  
  171.         if (x0 == 0)
  172.             x0 = 1;
  173.  
  174.         if (x1 == 0)
  175.             x1 = 1;
  176.  
  177.         if (y0 == 0)
  178.             y0 = 1;
  179.  
  180.         if (y1 == 0)
  181.             y1 = 1;
  182.  
  183.         int n = (max - min) / freq + 1;
  184.  
  185.         tick = new VerticalSliderTick[n];
  186.  
  187.         int vs = (y1 - y0) / (n - 1), ch;
  188.  
  189.         for (int i = 0; i < n; ++i) {
  190.             ch = i * vs;
  191.             tick[i] = new VerticalSliderTick(x0, x1, y0 + ch, ch);
  192.         }
  193.  
  194.         thumb.resize(x1 - x0 - TICK_WIDTH - 1, vs / 2);
  195.     }
  196.  
  197.     /**
  198.      * Moves and/or resizes this component.
  199.      * This is a standard Java AWT method which gets called to move and/or
  200.      * resize this component. Components that are in containers with layout
  201.      * managers should not call this method, but rely on the layout manager
  202.      * instead.
  203.      *
  204.      * @param x horizontal position in the parent's coordinate space
  205.      * @param y vertical position in the parent's coordinate space
  206.      * @param width the new width
  207.      * @param height the new height
  208.      */
  209.     public void reshape(int x, int y, int w, int h)
  210.     {
  211.         width  = w;
  212.         height = h;
  213.  
  214.         do_reshape(w, h);
  215.  
  216.         super.reshape(x, y, w, h);
  217.     }
  218.  
  219.     /**
  220.      * This routine updates the thumb position, paints the VerticalSlider, and
  221.      * posts a new action event, as needed. If the thumb position has
  222.      * changed or the forcePost parameter is true the component will be painted
  223.      * and an action event posted.
  224.      * @param pos the new thumb position
  225.      * @param forcePost true forces a repaint and posting of an action message 
  226.      * even if the thumb position hasn't changed
  227.      */
  228.     protected void doMove(int pos, boolean forcePost)
  229.     {
  230.         if (tick == null)
  231.         {
  232.             prevPos = curPos = pos;
  233.             return;
  234.         }
  235.  
  236.         if (pos >= tick.length)
  237.             pos = tick.length - 1;
  238.  
  239.         if (pos != curPos || forcePost)
  240.         {
  241.             prevPos = curPos;
  242.             curPos  = pos;
  243.             paint(getGraphics());
  244.  
  245.             postEvent(new Event(this, Event.ACTION_EVENT, new Integer(curPos * freq + min)));
  246.         }
  247.     }
  248.  
  249.     private void moveThumb(int y, boolean forcePost)
  250.     {
  251.         if (tick.length > 1)
  252.         {
  253.             int dist = tick[1].y - tick[0].y;
  254.  
  255.             if (dist == 0)
  256.                 return;
  257.  
  258.             int newPos = (y - tick[0].y) / dist;
  259.  
  260.             if (newPos < 0)
  261.                 newPos = 0;
  262.  
  263.             if (((y - tick[0].y) % dist) > (dist / 2))
  264.                 ++newPos;
  265.  
  266.             doMove(newPos, forcePost);
  267.         }
  268.     }
  269.  
  270.     /**
  271.      * Paints this component using the given graphics context.
  272.      * This is a standard Java AWT method which typically gets called
  273.      * by the AWT to handle painting this component. It paints this component
  274.      * using the given graphics context. The graphics context clipping region
  275.      * is set to the bounding rectangle of this component and its <0,0>
  276.      * coordinate is this component's top-left corner.
  277.      *
  278.      * @param g the graphics context used for painting
  279.      * @see java.awt.Component#repaint
  280.      * @see java.awt.Component#update
  281.      */
  282.     public void paint(Graphics g)
  283.     {
  284.         if (tick.length == 0)
  285.             return;
  286.  
  287.         VerticalSliderTick t;
  288.  
  289.         g.clipRect(0, 0, width, height);
  290.  
  291.         thumb.draw(g, tick[curPos]);
  292.  
  293.         if (prevPos != curPos)
  294.             thumb.clip(g, tick[prevPos]);
  295.  
  296.         g.setColor(getBackground());
  297.         g.fillRect(0, 0, width, height);
  298.  
  299.         g.setColor(Color.black);
  300.  
  301.         int x, y0, y1, w = width - 1, h = height - 1;
  302.         boolean end;
  303.  
  304.         if (showBorder)
  305.             g.drawRect(0, 0, w, h);
  306.  
  307.         for (int i = 0; i < tick.length; ++i)
  308.         {
  309.             end = i == 0 || i == tick.length - 1;
  310.  
  311.             t = tick[i];
  312.  
  313.             if (style == TICK_LEFT || style == TICK_BOTH)
  314.                 g.drawLine(t.x0 + (end ? 0 : 1), t.y, t.x0 + TICK_WIDTH, t.y);
  315.  
  316.             if (style == TICK_RIGHT || style == TICK_BOTH)
  317.                 g.drawLine(t.x1 - TICK_WIDTH, t.y, t.x1 - (end ? 0 : 1), t.y);
  318.         }
  319.  
  320.         t = tick[0];
  321.  
  322.         x  = (t.x1 + t.x0) / 2;
  323.         y0 = t.y - 5;
  324.         y1 = tick[tick.length - 1].y + 5;
  325.  
  326.         g.drawLine(x, y0, x, y1);
  327.  
  328.         g.setColor(Color.gray);
  329.         g.drawLine(x - 1, y1 + 1, x - 1, y0 - 1);
  330.         g.drawLine(x - 1, y0 - 1, x + 1, y0 - 1);
  331.  
  332.         g.setColor(Color.lightGray);
  333.         g.drawLine(x + 1, y0, x + 1, y1 + 1);
  334.         g.drawLine(x + 1, y1 + 1, x, y1 + 1);
  335.  
  336.         g.setColor(Color.white);
  337.         g.drawLine(x + 2, y0 - 1, x + 2, y1 + 2);
  338.         g.drawLine(x + 2, y1 + 2, x - 1, y1 + 2);
  339.  
  340.         g.clipRect(0, 0, width, height);
  341.  
  342.         thumb.draw(g, tick[curPos]);
  343.  
  344.         prevPos = curPos;
  345.     }
  346.     
  347.     /**
  348.      * Ensures that this component is laid out properly, as needed.
  349.      * This is a standard Java AWT method which gets called by the AWT to
  350.      * make sure this component and its subcomponents have a valid layout.
  351.      * If this component was made invalid with a call to invalidate(), then
  352.      * it is laid out again.
  353.      *
  354.      * @see java.awt.Component#invalidate
  355.      */
  356.     public void validate() {
  357.         super.validate();
  358.         
  359.         do_reshape(width, height);
  360.     }
  361. }
  362.  
  363.  
  364. class VerticalSliderTick
  365. {
  366.     int x0, x1, y, v;
  367.  
  368.     VerticalSliderTick(int ix0, int ix1, int iy, int iv)
  369.     {
  370.         x0 = ix0;
  371.         x1 = ix1;
  372.         y  = iy;
  373.  
  374.         v  = iv;
  375.     }
  376. }
  377.  
  378.  
  379. abstract class VerticalSliderThumb
  380. {
  381.     protected int x, y, width, height;
  382.     protected Graphics g;
  383.     protected VerticalSliderTick t;
  384.  
  385.     VerticalSliderThumb()
  386.     {
  387.     }
  388.  
  389.     void resize(int width, int height)
  390.     {
  391.         x = (this.width = width) - VerticalSlider.TICK_WIDTH - 1 - 1;
  392.         y = (this.height = height) / 2;
  393.     }
  394.  
  395.  
  396.     abstract void draw(Graphics g, VerticalSliderTick t);
  397.  
  398.  
  399.     protected void draw(int x0, int y0, int x1, int y1)
  400.     {
  401.         g.drawLine(t.x0 + x0 + VerticalSlider.TICK_WIDTH + 1, t.y + y0,
  402.                    t.x0 + x1 + VerticalSlider.TICK_WIDTH + 1, t.y + y1);
  403.     }
  404.  
  405.  
  406.     protected void initDraw(Graphics g, VerticalSliderTick t)
  407.     {
  408.         this.g = g;
  409.         this.t = t;
  410.  
  411.         g.setColor(Color.lightGray);
  412.         g.fillRect(t.x0 + 2 + VerticalSlider.TICK_WIDTH + 1, t.y - y + 1, x - 2, height - 2);
  413.  
  414.         g.setColor(Color.white);
  415.     }
  416.  
  417.  
  418.     void clip(Graphics g, VerticalSliderTick t)
  419.     {
  420.         g.clipRect(t.x0, t.y - height / 2, width + 1, height + 1);
  421.     }
  422. }
  423.  
  424.  
  425. class VerticalSliderThumbBoth extends VerticalSliderThumb
  426. {
  427.     void draw(Graphics g, VerticalSliderTick t)
  428.     {
  429.         super.initDraw(g, t);
  430.  
  431.         draw(x, -y, 1, -y);
  432.         draw(1, -y, 1, y);
  433.  
  434.         g.setColor(Color.black);
  435.         draw(x, -y, x, y);
  436.         draw(x, y, 1, y);
  437.  
  438.         g.setColor(Color.gray);
  439.  
  440.         draw(x - 1, -y + 1, x - 1, y - 1);
  441.         draw(x - 1, y - 1, 2, y - 1);
  442.     }
  443. }
  444.  
  445.  
  446. class VerticalSliderThumbLeft extends VerticalSliderThumb
  447. {
  448.     void draw(Graphics g, VerticalSliderTick t)
  449.     {
  450.         super.initDraw(g, t);
  451.  
  452.         int a = x / 4;
  453.  
  454.         draw(x, -y, a, -y);
  455.         draw(a, -y, 1, 0);
  456.  
  457.         g.setColor(Color.black);
  458.         draw(1, 0, a, y);
  459.         draw(a, y, x, y);
  460.         draw(x, y, x, -y);
  461.  
  462.         g.setColor(Color.gray);
  463.         draw(2, 0, a, y - 1);
  464.         draw(a, y - 1, x - 1, y - 1);
  465.         draw(x - 1, y - 1, x - 1, -y + 1);
  466.     }
  467. }
  468.  
  469.  
  470. class VerticalSliderThumbRight extends VerticalSliderThumb
  471. {
  472.     void draw(Graphics g, VerticalSliderTick t)
  473.     {
  474.         super.initDraw(g, t);
  475.  
  476.         int a = width - VerticalSlider.TICK_WIDTH - 1 - 1 - x / 4;
  477.  
  478.         draw(1, y, 1, -y);
  479.         draw(1, -y, a, -y);
  480.         draw(a, -y, x - 1, 0);
  481.  
  482.         g.setColor(Color.black);
  483.         draw(x, 0, a, y);
  484.         draw(a, y, 1, y);
  485.  
  486.         g.setColor(Color.gray);
  487.         draw(x - 1, 0, a, y - 1);
  488.         draw(a, y - 1, 2, y - 1);
  489.     }
  490. }
  491.  
  492.