home *** CD-ROM | disk | FTP | other *** search
/ Symantec Visual Cafe for Java 2.5 / symantec-visual-cafe-2.5-database-dev-edition.iso / VCafe / prosrc.bin / ComboCell.java < prev    next >
Encoding:
Java Source  |  1998-03-18  |  9.5 KB  |  297 lines

  1. /*
  2.  * Copyright (c) 1997 Krumel & Associates, Inc. All Rights Reserved.
  3.  *
  4.  * www.krumel.com - controls@krumel.com
  5.  *
  6.  * Permission is given to the buyer of this package for one software
  7.  * developer to use this software on one CPU (one workstation) and to make
  8.  * one backup copy.  You may uitilize and/or midfy this class for use in your
  9.  * projects.  You may distribute or sell any executable which results from
  10.  * using this code in your application, except a utility or class of similar
  11.  * nature to this product.  You may distribute this product in compiled
  12.  * form only, but soley to be used with your cmpiled executable product
  13.  * for the puposes of dynamic loading. You may NOT redistribute the source
  14.  * code in any form or make it accessible through a network or other
  15.  * distribution media to others. Please refer to the file "copyright.html"
  16.  * for further important copyright and licensing information.
  17.  *
  18.  * The source code is the confidential and proprietary information
  19.  * of Krumel & Associates, Inc. ("Confidential Information").  You shall
  20.  * not disclose such Confidential Information and shall use it only in
  21.  * accordance with the terms of the license agreement you entered into
  22.  * with Krumel & Associates, Inc..
  23.  
  24.  * KRUMEL & ASSOCIATES MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
  25.  * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
  26.  * NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  27.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. KRUMEL & ASSOCIATES SHALL NOT
  28.  * BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
  29.  * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  30.  */
  31.  
  32. package symantec.itools.db.awt;
  33.  
  34. import java.awt.*;
  35. import java.awt.event.*;
  36. import symantec.itools.db.awt.event.*;
  37.  
  38. /**
  39.  * Base class for cells that provide a drop-down widget or a popup interface.
  40.  */
  41. public abstract class ComboCell extends EditCell {
  42.     /**
  43.      * Combo-box style flag. If true then the user is allowed to type in the cell.
  44.      */
  45.     protected boolean         combo = true;
  46.  
  47.     /**
  48.      * The width of the arrow box for this cell.
  49.      */
  50.     protected int ARROW_WIDTH = 18;
  51.  
  52.     /**
  53.      * Creates a ComboCell that does not allow editing.
  54.      */
  55.     public ComboCell(Grid tv, DataSource ds) {
  56.         this(tv, ds, true);
  57.     }
  58.  
  59.     /**
  60.      * Creates a combo cell.
  61.      * @param comboBox True if cell should allow editing, false to not allow
  62.      *      editing.
  63.      */
  64.     public ComboCell(Grid tv, DataSource ds, boolean comboBox) {
  65.         super(tv, ds);
  66.         combo = comboBox;
  67.  
  68.         PAD_RIGHT = ARROW_WIDTH;
  69.     }
  70.  
  71.     /**
  72.      * Called when the user performs some action to indicate that the drop-down
  73.      * (or popup) should be cancelled. Calls Grid.hideAuxControl(). If the
  74.      * cell type does not use an aux control, then the Grid will ignore the call.
  75.      */
  76.     protected void dropDownCancelled() {
  77.         view.hideAuxControl();
  78.         view.redrawCell(this);
  79.     }
  80.  
  81.     /**
  82.      * Called when the button comes up signaling that the aux control should be
  83.      * hidden. Calls Grid.hideAuxControl(). If the cell type does not use
  84.      * an aux control, then the Grid will ignore the call.
  85.      */
  86.     protected void handleArrowRelease() {
  87.         view.hideAuxControl();
  88.         view.redrawCell(this);
  89.     }
  90.  
  91.     /**
  92.      * Makes the aux control visible and selects the item that mathces the
  93.      * current contents of the list, or the first item if there is not a match.
  94.      */
  95.     protected abstract void showAuxControl();
  96.  
  97.     //by default, displays aux control
  98.     protected void handleArrowPress() {
  99.         if (view.isAuxVisible()) {
  100.             view.hideAuxControl();
  101.             view.redrawCell(this);
  102.         } else {
  103.             showAuxControl();
  104.         }
  105.  
  106.         view.redrawCell(this);
  107.     }
  108.  
  109.     /**
  110.      * Called when the user presses the mouse on the cell to determine
  111.      * if the event occured over the arrow box.
  112.      */
  113.     protected boolean clickOnArrow(CellEvent e) {
  114.         Rectangle b = view.getCellBounds(this);
  115.  
  116.         if (b.width - e.getX() < ARROW_WIDTH
  117.             && e.getY()>0 && e.getY()<b.height && b.width-e.getX() > 0) {
  118.             return true;
  119.         }
  120.  
  121.         return false;
  122.     }
  123.  
  124.     /**
  125.      * Called when the user triggers a mouse event on the cell. If the left mouse
  126.      * button pushed, a check is made to see if occured on the arrow box. If so,
  127.      * handleArrowPress() is called, otherwise handleArrowRelease() is called.
  128.      */
  129.     public void mouseEvent(CellEvent e) {
  130.         if (e.getID() == CellEvent.MOUSE_PRESSED) {
  131.             if (clickOnArrow(e) && e.isLeftMouseButtonDown()) {
  132.                 handleArrowPress();
  133.                 return;
  134.             } else if (down()) {
  135.                 handleArrowRelease();
  136.             }
  137.         }
  138.  
  139.         super.mouseEvent(e);
  140.     }
  141.  
  142.     /**
  143.      * Callback method for adapter class to use when a drop-down widget fires
  144.      * an event indicating the user made a choice. By default, sets the value
  145.      * for the cell, highlights text and hides the aux control.
  146.      */
  147.     public void selectionMade(String item) {
  148.         Data        data;
  149.  
  150.         try {
  151.             data = getData();
  152.         } catch (DataNotAvailable ex) {
  153.             view.handleException(row(), col(), ex);
  154.             return;
  155.         }
  156.  
  157.         data.setText(item);
  158.         keyPressedYet = false;
  159.         selectionMade = false;
  160.         cursorPos = 0;
  161.         view.hideAuxControl();
  162.         view.redrawCell(this);
  163.     }
  164.  
  165.     /**
  166.      * If this is not a combo drop-down, all key events are ignored, o.w. if the
  167.      * down arrow is pressed, handleArrowPress() is called. In all other cases, the
  168.      * events are routed to the EditCell class for handling.
  169.      */
  170.     public void keyEvent(CellEvent e) {
  171.         if (!combo) {
  172.             //no cell editing allowed when not combo
  173.             return;
  174.         } else if (keyPressedYet && e.getKeyCode() == KeyEvent.VK_DOWN) {
  175.             handleArrowPress();
  176.             view.redrawCell(this);
  177.             return;
  178.         }
  179.  
  180.         super.keyEvent(e);
  181.     }
  182.  
  183.     /**
  184.      * Draws the text for the cell and calls drawArrow() to allow subclasses to
  185.      * draw the arrow box.
  186.      */
  187.     public void drawCell(Graphics g, CellHints hints) {
  188.         String      text;
  189.  
  190.         try {
  191.             text = readDataString();
  192.         } catch (DataNotAvailable ex) {
  193.             view.handleException(row(), col(), ex);
  194.             text = "ERROR";
  195.         }
  196.  
  197.         Rectangle   r = hints.bounds();
  198.         FontMetrics fm = view.getCellFontMetrics(this);
  199.         int         asc = fm.getAscent() + 1;
  200.  
  201.         int         sw = fm.stringWidth(text);
  202.         Color       oldfg = hints.fg;
  203.         int         origWidth = r.width;
  204.         int         origX = r.x;
  205.  
  206.         hints.setBackground(g);
  207.         g.fillRect(r.x, r.y, r.width-1, r.height-1);
  208.  
  209.         int rightPad = (isCurrentCell()) ?ARROW_WIDTH+5 :PAD_LEFT;
  210.         switch(hints.alignment()) {
  211.             case Grid.LEFT:
  212.                 r.x = origX + PAD_LEFT;
  213.                 break;
  214.             case Grid.CENTER:
  215.                 if (sw > r.width-(PAD_LEFT+rightPad)) {
  216.                     //won't fit so flush left
  217.                     r.x += PAD_LEFT;
  218.                 } else {
  219.                     //extra room so slide to the right
  220.                     r.x = r.x + (r.width-sw-rightPad)/2;
  221.                 }
  222.                 break;
  223.             case Grid.RIGHT:
  224.                 if (sw > r.width-(PAD_LEFT+rightPad)) {
  225.                     //won't fit so flush left
  226.                     r.x += PAD_LEFT;
  227.                 } else {
  228.                     //extra room so slide to the right
  229.                     r.x = origX+r.width-(sw+rightPad);
  230.                 }
  231.                 break;
  232.         }
  233.  
  234.         hints.setForeground(g);
  235.         r.width = r.width + origX - (r.x+rightPad-5);
  236.  
  237.         //draw the string
  238.         drawText(text, g, r, fm, hints);
  239.  
  240.         //draw cursor
  241.         if (isCurrentCell() && keyPressedYet) {
  242.             int cpos = 0;
  243.             if (text.length() > 0) {
  244.                 cpos = fm.stringWidth(text.substring(toLeftOfCell, cursorPos));
  245.             }
  246.             g.drawLine(r.x + cpos,
  247.                        r.y + 2,
  248.                        r.x + cpos,
  249.                        r.y + fm.getHeight());
  250.         }
  251.  
  252.  
  253.         r.x = origX;
  254.         r.width = origWidth;
  255.  
  256.         if (isCurrentCell()) {
  257.             drawArrow(g, r, hints);
  258.             r.width = r.width - ARROW_WIDTH;
  259.         }
  260.  
  261.         hints.drawBoundary(g);
  262.     }
  263.  
  264.     /**
  265.      * Draws the arrow button and calls drawSymbol() to draw graphic symbol.
  266.      */
  267.     protected void drawArrow(Graphics g, Rectangle r, CellHints hints) {
  268.         int left = r.x+r.width-ARROW_WIDTH;
  269.         int top = r.y;
  270.         int w = ARROW_WIDTH;
  271.         int ht = r.height;
  272.  
  273.         g.setColor(Color.lightGray);
  274.         g.fillRect(left, top, w, ht);
  275.         g.setColor(Color.black);
  276.         g.drawRect(left, top, w, ht);
  277.  
  278.         //add highlight
  279.         g.setColor(!down() ?Color.white  :Color.gray);
  280.         g.drawLine(left+1, top+2, left+1, top+ht-3);  //left
  281.         g.drawLine(left+1, top+2, left+w-3, top+2);   //top
  282.         g.setColor(down() ?Color.white  :Color.gray);
  283.         g.drawLine(left+w-3, top+2, left+w-3, top+ht-3); //right
  284.         g.drawLine(left+1, top+ht-3, left+w-3, top+ht-3); //bottom
  285.  
  286.         drawSymbol(g, top, left, w, ht);
  287.     }
  288.  
  289.     /**
  290.      * Returns whether the arrow box is currently depressed.
  291.      */
  292.     protected abstract boolean down();
  293.     /**
  294.      * Method to draw the arrow box symbol.
  295.      */
  296.     protected abstract void drawSymbol(Graphics g, int top, int left, int w, int ht);
  297. }