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 / ButtonCell.java < prev    next >
Encoding:
Java Source  |  1998-03-18  |  14.0 KB  |  454 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 modify this class for use in your
  9.  * projects.  You may distribute or sell any executable which results from
  10.  * using this code in yur 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.image.ImageObserver;
  36. import java.awt.event.*;
  37. import symantec.itools.db.awt.event.*;
  38.  
  39. /**
  40.  * A Grid cell containing a button.
  41.  * @see symantec.itools.db.awt.Grid
  42.  */
  43. public class ButtonCell implements TableCell, ImageObserver {
  44.     TableView           view;
  45.     DataSource          dataSource;
  46.     Coordinate          coords;
  47.     boolean             pressed;
  48.     boolean             drawUp = true;
  49.     boolean             defaultFlag;
  50.     int                 type;
  51.  
  52.     static final int   PADSIDES = 5;
  53.  
  54.     //this one is friendly
  55.     /**
  56.      * Constructs a default ButtonCell object.
  57.      */
  58.     ButtonCell() {}
  59.  
  60.     /**
  61.      * Constructs a ButtonCell.
  62.      * @param v The TableView the cell is contained within.
  63.      * @param ds The datasource the cell obtains its data.
  64.      */
  65.     public ButtonCell(TableView v, DataSource ds) {
  66.         view = v;
  67.         dataSource = ds;
  68.     }
  69.  
  70.     //one relative
  71.     /**
  72.      * Constructs a ButtonCell located at the given coordinates.
  73.      * @param r the one-relative row index
  74.      * @param c the one-relative column index
  75.      */
  76.     public ButtonCell(int r, int c) {
  77.         coords = new Coordinate(r-1, c-1);
  78.     }
  79.  
  80.     /**
  81.      * Gets the type of cell.
  82.      * @return One of CELL, COL_HEADING, ROW_HEADING, CORNER_CELL.
  83.      */
  84.     public int type() {
  85.         return type;
  86.     }
  87.  
  88.     /**
  89.      * Sets the type of cell.
  90.      * @param t One of CELL, COL_HEADING, ROW_HEADING, CORNER_CELL.
  91.      * @return One of CELL, COL_HEADING, ROW_HEADING, CORNER_CELL.
  92.      */
  93.     public int type(int t) {
  94.         if (t > CORNER_CELL || t < 0) {
  95.             throw new IllegalArgumentException("Invalid cell type");
  96.         }
  97.  
  98.         return type = t;
  99.     }
  100.  
  101.     /**
  102.      * Gets a copy of the cell suitable for taking the place of the current cell.
  103.      */
  104.     public TableCell cloneCell() {
  105.         ButtonCell bc = new ButtonCell(view, dataSource);
  106.  
  107.         if (coords != null) {
  108.             bc.coords = new Coordinate(coords);
  109.         }
  110.         bc.type = type;
  111.         bc.defaultFlag = defaultFlag;
  112.  
  113.         return bc;
  114.     }
  115.  
  116.     /**
  117.      * Allows the cell to set instance variables for view and data source.
  118.      * @param v The TableView the cell is contained within.
  119.      * @param ds The datasource the cell obtains its data.
  120.      */
  121.     public void setTableView(TableView v, DataSource ds) {
  122.         view = v;
  123.         dataSource = ds;
  124.     }
  125.  
  126.     /**
  127.      * Sets the cell as a default cell used by the TableView and data
  128.      * sources to conserve resources.
  129.      */
  130.     public void setDefaultFlag() { defaultFlag = true; }
  131.  
  132.     /**
  133.      * Resets the values of the cell to their default values.  The TableView uses
  134.      * common cells to perform the drawing and event functions.  This allows it to
  135.      * use memory efficiently by not being forced to create a cell for every piece of
  136.      * data stored in a data source.  This function is called when a cell is changed
  137.      * to represent another coordinate position.  Afterwards, the cell's methods are
  138.      * called to set the internal state properly before being asked to process
  139.      * cell events are perform drawing.
  140.      */
  141.     public void reset() {
  142.         pressed = false;
  143.         drawUp = true;
  144.     }
  145.  
  146.     /**
  147.      * Sets the cell coordinates for the cell. The coordinate parameter is a
  148.      * shared value, so its values should be copied to another variable of type
  149.      * Coordinate.
  150.      */
  151.     public void setCoordinates(Coordinate p) {
  152.         coords = p;
  153.     }
  154.  
  155.     /**
  156.      * Gets the cell coordinates for the cell.
  157.      */
  158.     public Coordinate getCoordinates() {
  159.         return coords;
  160.     }
  161.  
  162.     /**
  163.      * Gets the row number for the cell.
  164.      */
  165.     public int row() { return coords.row; }
  166.  
  167.     /**
  168.      * Sets the row number for the cell.
  169.      */
  170.     public void setRow(int r) { coords.row = r; }
  171.  
  172.     /**
  173.      * Gets the column number for the cell.
  174.      */
  175.     public int col() { return coords.col; }
  176.  
  177.     /**
  178.      * Sets the column number for the cell.
  179.      */
  180.     public void setCol(int c) { coords.col = c; }
  181.  
  182.     boolean inside(int x, int y) {
  183.         Rectangle r = view.getCellBounds(this);
  184.  
  185.         if (x > 0 && y > 0 && x < r.width && y < r.height) {
  186.             return true;
  187.         }
  188.  
  189.         return false;
  190.     }
  191.  
  192.     /**
  193.      * Called when the user triggers a mouse event on the cell.
  194.      */
  195.     public void mouseEvent(CellEvent e) {
  196.         if (e.getID() == CellEvent.MOUSE_PRESSED) {
  197.             view.setCapture(this);
  198.             pressed = true;
  199.             drawUp = false;
  200.             view.routeEvent(e);
  201.             view.redrawCell(this);
  202.         } else if (e.getID() == CellEvent.MOUSE_DRAGGED) {
  203.             if (inside(e.getX(), e.getY()) && drawUp) {
  204.                 drawUp = false;
  205.                 e.setID(CellEvent.BUTTON_FLICKER_DOWN_EVENT);
  206.                 view.routeEvent(e);
  207.                 view.redrawCell(this);
  208.             } else if (!inside(e.getX(), e.getY()) && !drawUp) {
  209.                 drawUp = true;
  210.                 e.setID(CellEvent.BUTTON_FLICKER_UP_EVENT);
  211.                 view.routeEvent(e);
  212.                 view.redrawCell(this);
  213.             }
  214.         } else if (e.getID() == CellEvent.MOUSE_RELEASED) {
  215.             if (pressed && !drawUp) {
  216.                 e.setID(CellEvent.BUTTON_UP_EVENT);
  217.                 view.routeEvent(e);
  218.             }
  219.  
  220.             pressed = false;
  221.             drawUp = true;
  222.             view.redrawCell(this);
  223.             view.lostCapture();
  224.         }
  225.     }
  226.  
  227.     /**
  228.      * Takes no action.
  229.      * @return <code>true</code>
  230.      */
  231.     public boolean auxControlEvent(Event e) { return true; }
  232.  
  233.     /**
  234.      * Gets the auxillary control for the cell.
  235.      * @return The widget if the cell supports auxillary controls or null
  236.      *      otherwise.
  237.      */
  238.     public Component auxControl() { return null; }
  239.  
  240.     /**
  241.      * Called by the TableView when it hides the auxillary control of the cell.
  242.      */
  243.     public void lostAuxControl() {}
  244.  
  245.     /**
  246.      * Gets the data object for the cell (Normally retrieved via the data source.
  247.      * @exception DataNotAvailable if the data cannot be accessed
  248.      */
  249.     public Data getData() throws DataNotAvailable {
  250.         return dataSource.getData(coords);
  251.     }
  252.  
  253.     String chopString(String text, FontMetrics fm, Rectangle r) {
  254.         int w = r.width;
  255.         int i = 1;
  256.         String t;
  257.  
  258.         if (text.length() == 0) { return text; }
  259.  
  260.  
  261.         do {
  262.             t = text.substring(0, i);
  263.         } while(fm.stringWidth(t) < w - PADSIDES*2 && i++ < text.length());
  264.  
  265.         return text.substring(0, i-1);
  266.     }
  267.  
  268.     /**
  269.      * Called by the TableView when the cell is to be drawn on the screen.
  270.      * @param g The graphics context to perform drawing functions.
  271.      * @param hints Contains the information required for the cell to draw
  272.      *      in the proper place and colors.
  273.      */
  274.     public void drawCell(Graphics g, CellHints hints) {
  275.         Data        data;
  276.  
  277.         try {
  278.             data = getData();
  279.         } catch (DataNotAvailable ex) {
  280.             data = new ImageStringData(dataSource, "");
  281.         }
  282.  
  283.  
  284.         Rectangle   r = hints.bounds();
  285.         FontMetrics fm = g.getFontMetrics();
  286.         int         asc = fm.getAscent() + 1;
  287.         String      text = chopString(data.toString(), fm, r);
  288.         int         sw = fm.stringWidth(text);
  289.         int         imageOffset = 0;
  290.         Color       fg = g.getColor();
  291.         int         origX = r.x;
  292.  
  293.         drawButton(g, hints);
  294.         Image im = data.toImage();
  295.         switch(hints.alignment()) {
  296.             case TableView.LEFT:
  297.                 if (im != null) {
  298.                     imageOffset = im.getWidth(this) + PADSIDES;
  299.                 }
  300.  
  301.                 //check to see if it will all fit within cell
  302.                 if (imageOffset+sw+2+PADSIDES <= r.width && im != null) {
  303.                     r.x += PADSIDES;
  304.                     r.y += 3;
  305.                     g.drawImage(im, r.x, r.y, this);
  306.                     r.y -= 3;
  307.                 } else {
  308.                     imageOffset = PADSIDES;
  309.                 }
  310.  
  311.                 r.x = origX + imageOffset + 2;
  312.                 break;
  313.             case TableView.CENTER:
  314.                 r.x = origX + (r.width-sw)/2;
  315.                 break;
  316.             case TableView.RIGHT:
  317.                 if (im != null) {
  318.                     imageOffset = im.getWidth(this) + PADSIDES;
  319.                 }
  320.                 //check to see if it will all fit within cell
  321.                 if (sw+imageOffset+2+PADSIDES <= r.width && im != null) {
  322.                     r.x = r.x + r.width - sw - PADSIDES - imageOffset - 2;
  323.                     r.y += 3;
  324.                     g.drawImage(im, r.x, r.y, this);
  325.                     r.y -= 3;
  326.                 }
  327.  
  328.                   r.x = origX+r.width-sw-PADSIDES;
  329.                 break;
  330.         }
  331.  
  332.         g.setColor(hints.foreground());
  333.  
  334.         g.drawString(text, r.x, r.y+fm.getAscent()+2);
  335.     }
  336.  
  337.     void drawButton(Graphics g, CellHints hints) {
  338.         //all highlighted and ready for delete
  339.         Rectangle r = hints.bounds();
  340.         g.setColor(hints.background());
  341.         g.fillRect(r.x,
  342.                    r.y,
  343.                    r.width-1,
  344.                    r.height);
  345.  
  346.         //draw shade for button
  347.         g.setColor(Color.gray);
  348.         g.drawRect(r.x+1, r.y+1, r.width-3, r.height-3);
  349.         g.setColor(Color.black);
  350.         g.drawRect(r.x, r.y, r.width-1, r.height-1);
  351.  
  352.         //draw the hightlight
  353.         if (drawUp) {
  354.             //draw button raised
  355.             g.setColor(Color.white);
  356.             g.drawLine(r.x+1, r.y+1, r.x + r.width-2, r.y+1);
  357.             g.drawLine(r.x+1, r.y+1, r.x+1, r.y + r.height - 2);
  358.         } else {
  359.             //draw button recessed
  360.             g.setColor(Color.white);
  361.             g.drawLine(r.x+1, r.y + r.height - 2, r.x + r.width-2, r.y + r.height-2);
  362.             g.drawLine(r.x + r.width - 2, r.y+1, r.x  + r.width - 2, r.y + r.height - 3);
  363.         }
  364.     }
  365.  
  366.     /**
  367.      * Queries whether the cell type supports user editing (normally from the
  368.      * keyboard.  If it cannot, the cell will not receive the keyboard focus.
  369.      */
  370.     public boolean isCellTypeEditable() { return false; }
  371.  
  372.     /**
  373.      * Takes no action.
  374.      * @return <code>true</code>
  375.      */
  376.     public boolean actionEvent(Event e) {
  377.         return true;
  378.     }
  379.  
  380.     /**
  381.      * Called by the TableView when the user triggers a key event while the
  382.      * cell possesses the keyboard focus.
  383.      */
  384.     public void keyEvent(CellEvent e) { }
  385.  
  386.     /**
  387.      * Called by the TableView when the cell possess the keyboard focus to query
  388.      * whether the cell's contents are in a valid state so another control may
  389.      * receive the keyboard focus.
  390.      */
  391.     public boolean canLoseFocus() { return true; }
  392.  
  393.     /**
  394.      * Called by the TableView when the cell either gains or loses the keyboard focus.
  395.      */
  396.     public void focusEvent(CellEvent e) {
  397.         if (e.getID() == CellEvent.GOT_FOCUS) {
  398.             view.setCapture(this);
  399.             view.routeEvent(e);
  400.         } else {
  401.             view.lostCapture();
  402.             view.routeEvent(e);
  403.         }
  404.    }
  405.  
  406.     /**
  407.      * Called by the TableView when the cell possesses the keyboard focus to
  408.      * query whether an arrow key can move the focus.
  409.      */
  410.     public boolean loseFocusOnArrow() {
  411.         return false;
  412.     }
  413.  
  414.     /**
  415.      * Informs the cell to draw a cursor if appropriate.  The TableView deactivates
  416.      * the cursor when it loses the keyboard focus.
  417.      */
  418.     public void activateCursor() {
  419.     }
  420.  
  421.     /**
  422.      * Informs the cell not to draw a cursor. The TableView deactivates the cursor
  423.      * when it loses the keyboard focus.
  424.      */
  425.     public void deactivateCursor() {
  426.     }
  427.  
  428.     /**
  429.      * Gets the key statistics of the cell in a String format. Helps with
  430.      * debugging.
  431.      */
  432.     public String stats() {
  433.         return "";
  434.     }
  435.  
  436.     /**
  437.      * Repaints the list when the cell's image has changed.
  438.      * @return true if image has changed; false otherwise.
  439.      */
  440.     public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h) {
  441.         if ((flags & (ABORT|ERROR)) != 0) {
  442.             return false;
  443.         }
  444.  
  445.         if ((flags & ALLBITS) != 0) {
  446.             view.redrawAsync();
  447.             return false;
  448.         } else {
  449.             return true;
  450.         }
  451.     }
  452. }
  453.  
  454.