Package DisplayProject

Source Code of DisplayProject.GridTitledBorder

/*
Copyright (c) 2003-2009 ITerative Consulting Pty Ltd. All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:

o Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
 
o Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the distribution.
   
o This jcTOOL Helper Class software, whether in binary or source form may not be used within,
or to derive, any other product without the specific prior written permission of the copyright holder

 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


*/
package DisplayProject;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;

import javax.swing.BorderFactory;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;

/**
* This border simulates the look and feel of forte grid border and is used on a GridFIeld
*
*/
public class GridTitledBorder extends TitledBorder {
    private static final long serialVersionUID = 4577391717413125796L;
    protected static final Color cHIGHLIGHT_COLOR = Color.white;
    protected static final Color cSHADOW_COLOR = new Color(172, 168, 153);
    protected Color frameColor = Color.black;
    protected int frameWeight = Constants.W_NONE;
    protected boolean spaceAtTopIfEmptyTitle = false;
    protected boolean enabled = true;

    public GridTitledBorder(Border border, String title, int titleJustification, int titlePosition, Font titleFont, Color titleColor) {
        super(border, title, titleJustification, titlePosition, titleFont, titleColor);
    }

    public GridTitledBorder(Border border, String title, int titleJustification, int titlePosition, Font titleFont) {
        super(border, title, titleJustification, titlePosition, titleFont);
    }

    public GridTitledBorder(Border border, String title, int titleJustification, int titlePosition) {
        super(border, title, titleJustification, titlePosition);
    }

    public GridTitledBorder(Border border, String title) {
        super(border, title);
        this.setTitleJustification(TitledBorder.LEFT);
        this.setTitlePosition(TitledBorder.TOP);
    }

    public GridTitledBorder(Border border) {
        super(border);
        this.setTitleJustification(TitledBorder.LEFT);
        this.setTitlePosition(TitledBorder.TOP);
    }
   
    public GridTitledBorder(String title) {
        super(title);
        this.setTitleJustification(TitledBorder.LEFT);
        this.setTitlePosition(TitledBorder.TOP);
    }

    public GridTitledBorder(String title, boolean spaceAtTopIfEmpty) {
      this(title);
      this.setSpaceAtTopIfEmptyTitle(spaceAtTopIfEmpty);
    }
    public GridTitledBorder() {
        super("");
        this.setTitleJustification(TitledBorder.LEFT);
        this.setTitlePosition(TitledBorder.TOP);
    }
   
    public void setSpaceAtTopIfEmptyTitle(boolean spaceAtTopIfEmptyTitle) {
    this.spaceAtTopIfEmptyTitle = spaceAtTopIfEmptyTitle;
  }
   
    public boolean hasTitle() {
        return (getTitle() != null && !(getTitle().length()==0));//PM:7 oct. 2008:performance
    }

    public Color getFrameColor() {
        return frameColor;
    }

    public void setFrameColor(Color frameColor) {
        this.frameColor = frameColor;
        this.titleColor = frameColor;
    }

    public int getFrameWeight() {
        return frameWeight;
    }

    public void setFrameWeight(int frameWeight) {
        switch (frameWeight){
            case Constants.W_DEFAULT : 
                this.setBorder(BorderFactory.createEtchedBorder(cHIGHLIGHT_COLOR, cSHADOW_COLOR));
                break;
            case Constants.W_NONE :       
                this.setBorder(BorderFactory.createEmptyBorder());
                break;
            default:
                // The lineWeightInPixels handles all the values.  CraigM: 28/01/2008.
                this.setBorder(new LineBorderWithColour(this.frameColor, UIutils.getLineWeightInPixels(frameWeight)));
                break;
        }
        this.frameWeight = frameWeight;
    }

    public Insets getBorderInsets(Component c, Insets insets) {
//        super.getBorderInsets(c, insets);
//        insets.left -= EDGE_SPACING + TEXT_SPACING;
//        insets.right -= EDGE_SPACING + TEXT_SPACING;
//        insets.bottom -= EDGE_SPACING + TEXT_SPACING;
//        // TF:30/8/07:Adjust the spacing minorly to bring into line with Forte. The Forte
//        // widgets start closer to the bottom of the caption text so compensate for this
//        // insets.top -= EDGE_SPACING + TEXT_SPACING + (hasTitle() ? 3 : 0);
//        Font font = getFont(c);
//
//        FontMetrics fm = c.getFontMetrics(font);
//        int descent = 0;
//        int ascent = 0;
//        int height = 0;
//        if(fm != null) {
//          descent = fm.getDescent();
//          ascent = fm.getAscent();
//          height = fm.getHeight();
//        }
//        insets.top -= EDGE_SPACING + TEXT_SPACING + ascent + descent
//
//        return insets;
      FontMetrics fm;
      int         descent = 0;
      int         ascent = 16;

      Border border = getBorder();
      if (border != null) {
        if (border instanceof AbstractBorder) {
          ((AbstractBorder)border).getBorderInsets(c, insets);
        } else {
          // Can't reuse border insets because the Border interface
          // can't be enhanced.
          Insets i = border.getBorderInsets(c);
          insets.top = i.top;
          insets.right = i.right;
          insets.bottom = i.bottom;
          insets.left = i.left;
        }
      } else {
        insets.left = insets.top = insets.right = insets.bottom = 0;
      }

      if(c == null || getTitle() == null || getTitle().equals(""))    {
        return insets;
      }

      Font font = getFont(c);

      fm = c.getFontMetrics(font);

      if(fm != null) {
        descent = fm.getDescent();
        ascent = fm.getAscent();
      }

      insets.top += Math.max(0, ascent + descent-1 - insets.top) ;
      return insets;

    }

    private java.awt.Point textLoc = new java.awt.Point();
    /**
     * Paints the border for the specified component with the
     * specified position and size. Shamelessly copied from the superclass
     * in order to override the location and size of the groove rectangle
     * to fit in with the Forte border.
     * @param c the component for which this border is being painted
     * @param g the paint graphics
     * @param x the x position of the painted border
     * @param y the y position of the painted border
     * @param width the width of the painted border
     * @param height the height of the painted border
     */
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        Border border = getBorder();
        Color color = g.getColor();
        g.setColor(frameColor);

        if (!spaceAtTopIfEmptyTitle && !hasTitle()) {
            if (border != null) {
                border.paintBorder(c, g, x, y, width, height);
            }
            g.setColor(color);
            return;
        }
        // TF:30/8/07: Compensate the spacing to make closer to Forte layout. The caption
        // starts further down from the top edge than Java, so fix this up. (only when we
        // have a caption though)
//        y += 1;
//        height -= 1;

        // In Forte the groove rectangle was right along the edge of the frame, so mirror this
        Rectangle grooveRect = new Rectangle(x, y, width, height);
        Font font = g.getFont();

        g.setFont(getFont(c));

        FontMetrics fm = c.getFontMetrics(getFont(c));
        int fontHeight = fm.getHeight();
        int descent = fm.getDescent();
        int ascent = fm.getAscent();
        int diff;
        int stringWidth = fm.stringWidth(getTitle());
        Insets insets;

        if (border != null) {
            insets = border.getBorderInsets(c);
        }
        else {
            insets = new Insets(0, 0, 0, 0);
        }

        int titlePos = getTitlePosition();
        switch (titlePos) {
            case ABOVE_TOP:
                diff = ascent + descent + (Math.max(EDGE_SPACING, TEXT_SPACING * 2) - EDGE_SPACING);
                grooveRect.y += diff;
                grooveRect.height -= diff;
                textLoc.y = grooveRect.y - (descent + TEXT_SPACING);
                break;
            case TOP:
            case DEFAULT_POSITION:
              textLoc.y = 0 + (ascent) + Math.max(0, insets.top - (ascent + descent)) /2;
              diff = Math.max(0, (ascent + descent - insets.bottom)/2);
              grooveRect.y += diff;
              grooveRect.height -= diff;
//                diff = Math.max(0, ((ascent / 2) + TEXT_SPACING) - EDGE_SPACING);
//                grooveRect.y += diff;
//                grooveRect.height -= diff;
//                textLoc.y = (grooveRect.y - descent) + (insets.top + ascent + descent) / 2;
                break;
            case BELOW_TOP:
                textLoc.y = grooveRect.y + insets.top + ascent + TEXT_SPACING;
                break;
            case ABOVE_BOTTOM:
                textLoc.y = (grooveRect.y + grooveRect.height) - (insets.bottom + descent + TEXT_SPACING);
                break;
            case BOTTOM:
                grooveRect.height -= fontHeight / 2;
                textLoc.y = ((grooveRect.y + grooveRect.height) - descent) + ((ascent + descent) - insets.bottom) / 2;
                break;
            case BELOW_BOTTOM:
                grooveRect.height -= fontHeight;
                textLoc.y = grooveRect.y + grooveRect.height + ascent + TEXT_SPACING;
                break;
        }

        int justification = getTitleJustification();
        if (justification == LEADING || justification == DEFAULT_JUSTIFICATION) {
            justification = LEFT;
        }
        else if (justification == TRAILING) {
            justification = RIGHT;
        }
        switch (justification) {
            case LEFT:
                textLoc.x = grooveRect.x + TEXT_INSET_H + insets.left;
                break;
            case RIGHT:
                textLoc.x = (grooveRect.x + grooveRect.width) - (stringWidth + TEXT_INSET_H + insets.right);
                break;
            case CENTER:
                textLoc.x = grooveRect.x + ((grooveRect.width - stringWidth) / 2);
                break;
        }

        // If title is positioned in middle of border AND its fontsize
        // is greater than the border's thickness, we'll need to paint
        // the border in sections to leave space for the component's background
        // to show through the title.
        //
        if (border != null) {
            if (((titlePos == TOP || titlePos == DEFAULT_POSITION) /*&& (grooveRect.y > textLoc.y - ascent)*/)
                    || (titlePos == BOTTOM && (grooveRect.y + grooveRect.height < textLoc.y + descent))) {

                Rectangle clipRect = new Rectangle();

                // save original clip
                Rectangle saveClip = g.getClipBounds();

                if (hasTitle() || !spaceAtTopIfEmptyTitle) {
                  // paint strip left of text
                  clipRect.setBounds(saveClip);
                  if (computeIntersection(clipRect, x, y, textLoc.x - 1 - x, height)) {
                      g.setClip(clipRect);
                      border.paintBorder(c, g, grooveRect.x, grooveRect.y, grooveRect.width, grooveRect.height);
                  }
 
                  // paint strip right of text
                  clipRect.setBounds(saveClip);
                  if (computeIntersection(clipRect, textLoc.x + stringWidth + 1, y, x + width
                          - (textLoc.x + stringWidth + 1), height)) {
                      g.setClip(clipRect);
                      border.paintBorder(c, g, grooveRect.x, grooveRect.y, grooveRect.width, grooveRect.height);
                  }
                }
                else {
                  // Some forte controls, like radio buttons, still paint the border down a little, even if there's
                  // no text. We need to mirror this functionality
                  clipRect.setBounds(saveClip);
                  if (computeIntersection(clipRect, x, y, x + width, height)) {
                      g.setClip(clipRect);
                      border.paintBorder(c, g, grooveRect.x, grooveRect.y, grooveRect.width, grooveRect.height);
                  }
                }
                if (titlePos == TOP || titlePos == DEFAULT_POSITION) {
                    // paint strip below text
                    clipRect.setBounds(saveClip);
                    if (computeIntersection(clipRect, textLoc.x - 1, textLoc.y + descent, stringWidth + 2, y + height
                            - textLoc.y - descent)) {
                        g.setClip(clipRect);
                        border.paintBorder(c, g, grooveRect.x, grooveRect.y, grooveRect.width, grooveRect.height);
                    }

                }
                else { // titlePos == BOTTOM
                    // paint strip above text
                    clipRect.setBounds(saveClip);
                    if (computeIntersection(clipRect, textLoc.x - 1, y, stringWidth + 2, textLoc.y - ascent - y)) {
                        g.setClip(clipRect);
                        border.paintBorder(c, g, grooveRect.x, grooveRect.y, grooveRect.width, grooveRect.height);
                    }
                }

                // restore clip
                g.setClip(saveClip);

            }
            else {
                border.paintBorder(c, g, grooveRect.x, grooveRect.y, grooveRect.width, grooveRect.height);
            }
        }

        // COLET 12/01/2009 : Added option of painting the title as disabled.
        if(isEnabled()) {
          paintEnabledText(g, getTitle(), textLoc.x, textLoc.y);
        } else {
          paintDisabledText(c, g, getTitle(), textLoc.x, textLoc.y);
        }

        g.setFont(font);
        g.setColor(color);
    }
   
    /**
     * Paint clippedText at textX, textY with background.lighter() and then
     * shifted down and to the right by one pixel with background.darker().
     *
     * @see #paintBorder
     * @see #paintEnabledText
     */
    protected void paintDisabledText(Component c, Graphics g, String s, int textX, int textY)
    {
      Color componentBackground = c.getBackground();
      // Use our background colour as foreground colour, if none set, just use the default.
        Color foreground = componentBackground != null ? componentBackground : getDefaultDisabledTitleColour();
        g.setColor(foreground.brighter());
        g.drawString(s, textX+1, textY+1);
        g.setColor(foreground.darker());
        g.drawString(s, textX, textY);
    }

  /**
   * Colour to use as the Title Text Colour when disabled and the components background colour can not be determined.
   * @return UIutils.Gray2
   */
  protected Color getDefaultDisabledTitleColour()
  {
    return UIutils.Gray2;
  }
   
    /**
     * Paint clippedText at textX, textY with getTitleColor().
     *
     * @see #paintBorder
     * @see #paintDisabledText
     */
    protected void paintEnabledText(Graphics g, String s, int textX, int textY)
    {
        g.setColor(getTitleColor());
        g.drawString(s, textX, textY);
    }
   
    private static boolean computeIntersection(Rectangle dest, int rx, int ry, int rw, int rh) {
        int x1 = Math.max(rx, dest.x);
        int x2 = Math.min(rx + rw, dest.x + dest.width);
        int y1 = Math.max(ry, dest.y);
        int y2 = Math.min(ry + rh, dest.y + dest.height);
        dest.x = x1;
        dest.y = y1;
        dest.width = x2 - x1;
        dest.height = y2 - y1;

        if (dest.width <= 0 || dest.height <= 0) {
            return false;
        }
        return true;
    }

  /**
   * Determine if the Titled Border Enabled.
   * @return true if enabled, false otherwise.
   */
  public boolean isEnabled()
  {
    return enabled;
  }

  /**
   * Set the Titled Border Enabled/Disabled. This changes the way the Border is painted.
   *
   * @see #paintBorder
   * @see #paintDisabledText
   * @see #paintEnabledText
   * @param enabled true to enable, false to disable.
   */
  public void setEnabled(boolean enabled)
  {
    this.enabled = enabled;
 

}
TOP

Related Classes of DisplayProject.GridTitledBorder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.