home *** CD-ROM | disk | FTP | other *** search
/ Java Developer's Companion / Java Developer's Companion.iso / documentation / tutorial / intl / collation / demos-1.1 / BorderPanel.java next >
Encoding:
Java Source  |  1997-07-13  |  16.4 KB  |  569 lines

  1. /*
  2.  * Copyright (c) 1995-1997 Sun Microsystems, Inc. All Rights Reserved.
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software
  5.  * and its documentation for NON-COMMERCIAL purposes and without
  6.  * fee is hereby granted provided that this copyright notice
  7.  * appears in all copies. Please refer to the file "copyright.html"
  8.  * for further important copyright and licensing information.
  9.  *
  10.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  11.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  12.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  13.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  14.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  15.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  16.  */
  17. /* ************************************************************* */
  18. /* (C) Copyright Taligent, Inc. 1996-All Rights Reserved.        */
  19. /* (C) Copyright IBM Corporation 1996                            */
  20. /*                                                               */
  21. /* Permission is granted to copy, use, modify, and merge this    */
  22. /* software into your applications  and to permit others to do      */
  23. /* any of the foregoing. You must include this permission and      */
  24. /* copyright notice in all copies and modified versions of this  */
  25. /* software, and include attribution to Taligent in all splash      */
  26. /* screens included in any application using this software.      */
  27. /* THIS SOFTWARE IS PROVIDED IN ITS 'AS IS' CONDITION. TALIGENT  */
  28. /* DISCLAIMS ANY LIABILITY OF ANY KIND FOR DAMAGES WHATSOEVER      */
  29. /* RESULTING FROM THE USE OF THIS SOFTWARE.                         */
  30. /* ************************************************************* */
  31.  
  32. import java.awt.*;
  33.  
  34. /**
  35.  * Various graphical borders. The border itself is a Panel so that it can
  36.  * contain other Components (i.e. it borders something). You use the
  37.  * BorderPanel like any other Panel: you set the layout that you prefer and
  38.  * add Components to it. Beware that a null layout does not obey the insets
  39.  * of the panel so if you use null layouts, adjust your measurements to
  40.  * handle the border by calling getInsets().
  41.  *
  42.  * @author  Andy Clark, Taligent Inc.
  43.  * @version 1.0
  44.  */
  45. public class BorderPanel
  46.     extends Panel
  47.     {
  48.     // Constants
  49.  
  50.     /** Solid border. */
  51.     public final static int SOLID = 0;
  52.     /** A raised border. */
  53.     public final static int RAISED = 1;
  54.     /** A lowered border. */
  55.     public final static int LOWERED = 2;
  56.     /** An etched in border. */
  57.     public final static int IN = 3;
  58.     /** An etched out border. */
  59.     public final static int OUT = 4;
  60.  
  61.     /** Left alignment. */
  62.     public final static int LEFT = 0;
  63.     /** Center alignment. */
  64.     public final static int CENTER = 1;
  65.     /** Right alignment. */
  66.     public final static int RIGHT = 2;
  67.  
  68.     /** Default style (IN). */
  69.     public final static int DEFAULT_STYLE = IN;
  70.     /** Default thickness (10). */
  71.     public final static int DEFAULT_THICKNESS = 10;
  72.     /** Default thickness for solid borders (4). */
  73.     public final static int DEFAULT_SOLID_THICKNESS = 4;
  74.     /** Default thickness for raised borders (2). */
  75.     public final static int DEFAULT_RAISED_THICKNESS = 2;
  76.     /** Default thickness for lowered borders (2). */
  77.     public final static int DEFAULT_LOWERED_THICKNESS = 2;
  78.     /** Default thickness for etched-in borders (10). */
  79.     public final static int DEFAULT_IN_THICKNESS = 10;
  80.     /** Default thickness for etched-out borders (10). */
  81.     public final static int DEFAULT_OUT_THICKNESS = 10;
  82.     /** Default gap between border and contained component (5). */
  83.     public final static int DEFAULT_GAP = 5;
  84.     /** Default color (black). Applies to SOLID and etched borders. */
  85.     public final static Color DEFAULT_COLOR = Color.black;
  86.  
  87.     /** Default font (TimesRoman,PLAIN,14). Only applies to etched borders. */
  88.     public final static Font DEFAULT_FONT = new Font("TimesRoman", Font.PLAIN, 14);
  89.     /** Default alignment (LEFT). Only applies to etched borders. */
  90.     public final static int DEFAULT_ALIGNMENT = LEFT;
  91.  
  92.     // Data
  93.     private int style;
  94.     private int thickness;
  95.     private int gap;
  96.     private Color color;
  97.  
  98.     private Font font;
  99.     private String text;
  100.     private int alignment;
  101.  
  102.     /**
  103.      * Constructor. Makes default border.
  104.      */
  105.     public BorderPanel() {
  106.  
  107.         // initialize data
  108.         style       = DEFAULT_STYLE;
  109.         thickness   = DEFAULT_THICKNESS;
  110.         gap         = DEFAULT_GAP;
  111.         color       = DEFAULT_COLOR;
  112.  
  113.         text        = null;
  114.         font        = DEFAULT_FONT;
  115.         alignment   = DEFAULT_ALIGNMENT;
  116.  
  117.         }
  118.  
  119.     /**
  120.      * Constructor. Makes an etched IN border with given text caption.
  121.      *
  122.      * @param text  Text caption
  123.      */
  124.     public BorderPanel(String text) {
  125.         this();
  126.  
  127.         style = IN;
  128.         this.text = text;
  129.         }
  130.  
  131.     /**
  132.      * Constructor. Makes SOLID border with color and thickness given.
  133.      *
  134.      * @param color     The color for the border.
  135.      * @param thickness The thickness of the border.
  136.      */
  137.     public BorderPanel(Color color, int thickness) {
  138.         this();
  139.  
  140.         style = SOLID;
  141.         this.color = color;
  142.         this.thickness = thickness;
  143.         }
  144.  
  145.     /**
  146.      * Constructor. Makes a border of the given style with the default
  147.      * thickness for that style.
  148.      *
  149.      * @param style The style for this border.
  150.      */
  151.     public BorderPanel(int style) {
  152.         this();
  153.  
  154.         // set thickness appropriate to this style
  155.         int thickness;
  156.         switch (style) {
  157.             case SOLID: thickness = DEFAULT_SOLID_THICKNESS; break;
  158.             case RAISED: thickness = DEFAULT_RAISED_THICKNESS; break;
  159.             case LOWERED: thickness = DEFAULT_LOWERED_THICKNESS; break;
  160.             case IN: thickness = DEFAULT_IN_THICKNESS; break;
  161.             case OUT: thickness = DEFAULT_OUT_THICKNESS; break;
  162.             default:
  163.                 thickness = DEFAULT_THICKNESS;
  164.             }
  165.  
  166.         this.style = style;
  167.         this.thickness = thickness;
  168.         }
  169.  
  170.     /**
  171.      * Constructor. Makes border with given style and thickness.
  172.      *
  173.      * @param style     The style for this border.
  174.      * @param thickness The thickness for this border.
  175.      */
  176.     public BorderPanel(int style, int thickness) {
  177.         this();
  178.  
  179.         this.style = style;
  180.         this.thickness = thickness;
  181.         }
  182.  
  183.     /**
  184.      * Returns the insets of this panel..
  185.      */
  186.     public Insets getInsets() {
  187.         int adjustment = 0;
  188.  
  189.         // adjust for text string
  190.         if (style == IN || style == OUT) {
  191.             if (text != null && text.length() > 0) {
  192.                 try {
  193.                     // set font and get info
  194.                     int height = getGraphics().getFontMetrics(font).getHeight();
  195.                     if (height > thickness)
  196.                         adjustment = height - thickness;
  197.                     }
  198.                 catch (Exception e) {
  199.                     // nothing: just in case there is no graphics context
  200.                     //   at the beginning.
  201.                     }
  202.                 }
  203.             }
  204.  
  205.         // return appropriate insets
  206.         int dist = thickness + gap;
  207.         return new Insets(dist + adjustment, dist, dist, dist);
  208.         }
  209.  
  210.     /**
  211.      * Sets the style of the border
  212.      *
  213.      * @param style The new style.
  214.      */
  215.     public BorderPanel setStyle(int style) {
  216.  
  217.         // set the style and re-layout the panel
  218.         this.style = style;
  219.         doLayout();
  220.         repaint();
  221.  
  222.         return this;
  223.         }
  224.  
  225.     /**
  226.      * Gets the style of the border
  227.      */
  228.     public int getStyle() {
  229.  
  230.         return style;
  231.         }
  232.  
  233.     /**
  234.      * Sets the thickness of the border.
  235.      *
  236.      * @param thickness The new thickness
  237.      */
  238.     public BorderPanel setThickness(int thickness) {
  239.  
  240.         if (thickness > 0) {
  241.             this.thickness = thickness;
  242.             doLayout();
  243.             repaint();
  244.             }
  245.  
  246.         return this;
  247.         }
  248.  
  249.     /**
  250.      * Gets the thickness of the border.
  251.      */
  252.     public int getThickness() {
  253.  
  254.         return thickness;
  255.         }
  256.  
  257.     /**
  258.      * Sets the gap between the border and the contained Component.
  259.      *
  260.      * @param gap The new gap, in pixels.
  261.      */
  262.     public BorderPanel setGap(int gap) {
  263.  
  264.         if (gap > -1) {
  265.             this.gap = gap;
  266.             doLayout();
  267.             repaint();
  268.             }
  269.  
  270.         return this;
  271.         }
  272.  
  273.     /**
  274.      * Gets the gap between the border and the contained Component.
  275.      */
  276.     public int getGap() {
  277.  
  278.         return gap;
  279.         }
  280.  
  281.     /**
  282.      * Sets the current color for SOLID borders and the caption text
  283.      * color for etched borders.
  284.      *
  285.      * @param color The new color.
  286.      */
  287.     public BorderPanel setColor(Color color) {
  288.  
  289.         this.color = color;
  290.         if (style == SOLID || style == IN || style == OUT)
  291.             repaint();
  292.  
  293.         return this;
  294.         }
  295.  
  296.     /**
  297.      * Gets the current color for SOLID borders and the caption
  298.      * text color for etched borders.
  299.      */
  300.     public Color getColor() {
  301.  
  302.         return color;
  303.         }
  304.  
  305.     /**
  306.      * Sets the font. Only applies to etched borders.
  307.      */
  308.     public BorderPanel setTextFont(Font font) {
  309.  
  310.         // set font
  311.         if (font != null) {
  312.             this.font = font;
  313.             if (style == IN || style == OUT) {
  314.                 doLayout();
  315.                 repaint();
  316.                 }
  317.             }
  318.  
  319.         return this;
  320.         }
  321.  
  322.     /**
  323.      * Gets the font of the text. Only applies to etched borders.
  324.      */
  325.     public Font getTextFont() {
  326.  
  327.         return font;
  328.         }
  329.  
  330.     /**
  331.      * Sets the text. Only applies to etched borders.
  332.      *
  333.      * @param text  The new text.
  334.      */
  335.     public BorderPanel setText(String text) {
  336.  
  337.         this.text = text;
  338.         if (style == IN || style == OUT) {
  339.             doLayout();
  340.             repaint();
  341.             }
  342.  
  343.         return this;
  344.         }
  345.  
  346.     /**
  347.      * Gets the text. Only applies to etched borders.
  348.      */
  349.     public String getText() {
  350.  
  351.         return text;
  352.         }
  353.  
  354.     /**
  355.      * Sets the text alignment. Only applies to etched borders.
  356.      *
  357.      * @param alignment The new alignment.
  358.      */
  359.     public BorderPanel setAlignment(int alignment) {
  360.  
  361.         this.alignment = alignment;
  362.         if (style == IN || style == OUT) {
  363.             doLayout();
  364.             repaint();
  365.             }
  366.  
  367.         return this;
  368.         }
  369.  
  370.     /**
  371.      * Gets the text alignment.
  372.      */
  373.     public int getAlignment() {
  374.  
  375.         return alignment;
  376.         }
  377.  
  378.     /**
  379.      * Repaints the border.
  380.      *
  381.      * @param g The graphics context.
  382.      */
  383.     public void paint(Graphics g) {
  384.  
  385.         // get current dimensions
  386.         Dimension size = getSize();
  387.         int width = size.width;
  388.         int height = size.height;
  389.  
  390.         // set colors
  391.         Color light = getBackground().brighter().brighter().brighter();
  392.         Color dark = getBackground().darker().darker().darker();
  393.  
  394.         // Draw border
  395.         switch (style) {
  396.             case RAISED:    // 3D Border (in or out)
  397.             case LOWERED:
  398.                 Color topleft = null;
  399.                 Color bottomright = null;
  400.  
  401.                 // set colors
  402.                 if (style == RAISED) {
  403.                     topleft = light;
  404.                     bottomright = dark;
  405.                     }
  406.                 else {
  407.                     topleft = dark;
  408.                     bottomright = light;
  409.                     }
  410.  
  411.                 // draw border
  412.                 g.setColor(topleft);
  413.                 for (int i = 0; i < thickness; i++) {
  414.                     g.drawLine(i, i, width - i - 2, i);
  415.                     g.drawLine(i, i + 1, i, height - i - 1);
  416.                     }
  417.                 g.setColor(bottomright);
  418.                 for (int i = 0; i < thickness; i++) {
  419.                     g.drawLine(i + 1, height - i - 1, width - i - 1, height - i - 1);
  420.                     g.drawLine(width - i - 1, i, width - i - 1, height - i - 2);
  421.                     }
  422.                 break;
  423.  
  424.             case IN:    // Etched Border (in or out)
  425.             case OUT:
  426.                 int adjust1 = 0;
  427.                 int adjust2 = 0;
  428.  
  429.                 // set font and get info
  430.                 Font oldfont = g.getFont();
  431.                 g.setFont(font);
  432.                 FontMetrics fm = g.getFontMetrics();
  433.                 int ascent = fm.getAscent();
  434.  
  435.                 // set adjustment
  436.                 if (style == IN)
  437.                     adjust1 = 1;
  438.                 else
  439.                     adjust2 = 1;
  440.  
  441.                 // Calculate adjustment for text
  442.                 int adjustment = 0;
  443.                 if (text != null && text.length() > 0) {
  444.                     if (ascent > thickness)
  445.                         adjustment = (ascent - thickness) / 2;
  446.                     }
  447.  
  448.                 // The adjustment is there so that we always draw the
  449.                 // light rectangle first. Otherwise, your eye picks up
  450.                 // the discrepancy where the light rect. passes over
  451.                 // the darker rect.
  452.                 int x = thickness / 2;
  453.                 int y = thickness / 2 + adjustment;
  454.                 int w = width - thickness - 1;
  455.                 int h = height - thickness - 1 - adjustment;
  456.  
  457.                 // draw rectangles
  458.                 g.setColor(light);
  459.                 g.drawRect(x + adjust1, y + adjust1, w, h);
  460.                 g.setColor(dark);
  461.                 g.drawRect(x + adjust2, y + adjust2, w, h);
  462.  
  463.                 // draw text, if applicable
  464.                 if (text != null && text.length() > 0) {
  465.                     // calculate drawing area
  466.                     int fontheight = fm.getHeight();
  467.                     int strwidth = fm.stringWidth(text);
  468.  
  469.                     int textwidth = width - 2 * (thickness + 5);
  470.                     if (strwidth > textwidth)
  471.                         strwidth = textwidth;
  472.  
  473.                     // calculate offset for alignment
  474.                     int offset;
  475.                     switch (alignment) {
  476.                         case CENTER:
  477.                             offset = (width - strwidth) / 2;
  478.                             break;
  479.                         case RIGHT:
  480.                             offset = width - strwidth - thickness - 5;
  481.                             break;
  482.                         case LEFT:
  483.                         default: // assume left alignment if invalid
  484.                             offset = thickness + 5;
  485.                             break;
  486.                         }
  487.  
  488.                     // clear drawing area and set clipping region
  489.                     g.clearRect(offset - 5, 0, strwidth  + 10, fontheight);
  490.                     g.clipRect(offset, 0, strwidth, fontheight);
  491.  
  492.                     // draw text
  493.                     g.setColor(color);
  494.                     g.drawString(text, offset, ascent);
  495.  
  496.                     // restore old clipping area
  497.                     g.clipRect(0, 0, width, height);
  498.                     }
  499.  
  500.                 g.setFont(oldfont);
  501.                 break;
  502.  
  503.             case SOLID:
  504.             default: // assume SOLID
  505.                 g.setColor(color);
  506.                 for (int i = 0; i < thickness; i++)
  507.                     g.drawRect(i, i, width - 2 * i - 1, height - 2 * i - 1);
  508.             }
  509.  
  510.         }
  511.  
  512.     /**
  513.      * Returns the settings of this BorderPanel instance as a string.
  514.      */
  515.     public String toString() {
  516.         StringBuffer str = new StringBuffer("BorderPanel[");
  517.  
  518.         // style
  519.         str.append("style=");
  520.         switch (style) {
  521.             case SOLID: str.append("SOLID"); break;
  522.             case RAISED: str.append("RAISED"); break;
  523.             case LOWERED: str.append("LOWERED"); break;
  524.             case IN: str.append("IN"); break;
  525.             case OUT: str.append("OUT"); break;
  526.             default: str.append("unknown");
  527.             }
  528.         str.append(",");
  529.  
  530.         // thickness
  531.         str.append("thickness=");
  532.         str.append(thickness);
  533.         str.append(",");
  534.  
  535.         // gap
  536.         str.append("gap=");
  537.         str.append(gap);
  538.         str.append(",");
  539.  
  540.         // color
  541.         str.append(color);
  542.         str.append(",");
  543.  
  544.         // font
  545.         str.append(font);
  546.         str.append(",");
  547.  
  548.         // text
  549.         str.append("text=");
  550.         str.append(text);
  551.         str.append(",");
  552.  
  553.         // alignment
  554.         str.append("alignment=");
  555.         switch (alignment) {
  556.             case LEFT: str.append("LEFT"); break;
  557.             case CENTER: str.append("CENTER"); break;
  558.             case RIGHT: str.append("RIGHT"); break;
  559.             default: str.append("unknown");
  560.             }
  561.  
  562.         str.append("]");
  563.  
  564.         return str.toString();
  565.         }
  566.  
  567.     }
  568.  
  569.