All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.codename1.ui.plaf.Border Maven / Gradle / Ivy

There is a newer version: 7.0.164
Show newest version
/*
 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores
 * CA 94065 USA or visit www.oracle.com if you need additional information or
 * have any questions.
 */
package com.codename1.ui.plaf;

import com.codename1.ui.Component;
import com.codename1.ui.Display;
import com.codename1.ui.Font;
import com.codename1.ui.Graphics;
import com.codename1.ui.Image;
import com.codename1.ui.ImageFactory;
import com.codename1.ui.Painter;
import com.codename1.ui.RGBImage;
import com.codename1.ui.geom.Rectangle;

/**
 * Base class that allows us to render a border for a component, a border is drawn before
 * the component and is drawn within the padding region of the component. It is the
 * responsibility of the component not to draw outside of the border line.
 * 

This class can be extended to provide additional border types and custom made * border types. *

A border can optionally paint the background of the component, this depends on * the border type and is generally required for rounded borders that "know" the area * that should be filled. * * @author Shai Almog */ public class Border { private static Border defaultBorder = Border.createEtchedRaised(0x020202, 0xBBBBBB); private static final int TYPE_EMPTY = 0; private static final int TYPE_LINE = 1; private static final int TYPE_ROUNDED = 2; private static final int TYPE_ROUNDED_PRESSED = 3; private static final int TYPE_ETCHED_LOWERED = 4; private static final int TYPE_ETCHED_RAISED = 5; private static final int TYPE_BEVEL_RAISED = 6; private static final int TYPE_BEVEL_LOWERED = 7; private static final int TYPE_IMAGE = 8; private static final int TYPE_COMPOUND = 9; private static final int TYPE_IMAGE_HORIZONTAL = 10; private static final int TYPE_IMAGE_VERTICAL = 11; private static final int TYPE_DASHED = 12; private static final int TYPE_DOTTED = 13; private static final int TYPE_DOUBLE = 14; private static final int TYPE_GROOVE = 15; private static final int TYPE_RIDGE = 16; private static final int TYPE_INSET = 17; private static final int TYPE_OUTSET = 18; private static final int TYPE_IMAGE_SCALED = 19; private static final int TYPE_UNDERLINE = 21; // variables are package protected for the benefit of the resource editor! int type; Image[] images; private Image[] specialTile; private Rectangle trackComponent; /** * Indicates whether theme colors should be used or whether colors are specified * in the border */ boolean themeColors; int colorA; int colorB; int colorC; int colorD; float thickness = 0; boolean millimeters; int arcWidth; int arcHeight; boolean outline = true; Border pressedBorder; Border focusBorder; Border [] compoundBorders; Border outerBorder; // A border added outside of this border (Used for CSS outline property, but can also be used for other purposes) String borderTitle; // border title, currently supported only for line borders private boolean paintOuterBorderFirst; private static final int TITLE_MARGIN = 10; private static final int TITLE_SPACE = 5; private static Border empty; private boolean emptyType; /** * Prevents usage of new operator, use the factory methods in the class or subclass * to create new border types. */ protected Border() { } /** * If a border is a horizontal image border it can be mirrored which is useful for an RTL scenario * * @return the current border or a mirrored instance */ public Border mirrorBorder() { if(type == TYPE_IMAGE_HORIZONTAL) { return createHorizonalImageBorder(images[1].mirror(), images[0].mirror(), images[2].mirror()); } return this; } /** * This method is designed mainly for the purpose of creating an arrow that will track a specific component using the image border * the tile given would be an arrow like image just like the ones used for the top/bottom/left/right images. This image would be positioned * so it points at the center of the track component * * @param tileTop an image that will replace one of the tiles on the top if the track component is there * @param tileBottom an image that will replace one of the tiles on the bottom if the track component is there * @param tileLeft an image that will replace one of the tiles on the left if the track component is there * @param tileRight an image that will replace one of the tiles on the right if the track component is there * @param trackComponent the component that will be tracked for the positioning of the tile */ public void setImageBorderSpecialTile(Image tileTop, Image tileBottom, Image tileLeft, Image tileRight, Component trackComponent) { specialTile = new Image[] {tileTop, tileBottom, tileLeft, tileRight}; this.trackComponent = new Rectangle(trackComponent.getAbsoluteX(), trackComponent.getAbsoluteY(), trackComponent.getWidth(), trackComponent.getHeight()); } /** * The track component is an area to which an arrow based border should point at. * It's assumed to be outside of the border region in absolute screen coordinates. * * @return the rectangle to point at or null if this isn't an arrow border */ protected Rectangle getTrackComponent() { return trackComponent; } /** * In the case of an arrow border the track component lets us track the position * to which the border is pointing * @param trackComponent the track component */ public void setTrackComponent(Component trackComponent) { this.trackComponent = new Rectangle(trackComponent.getAbsoluteX(), trackComponent.getAbsoluteY(), trackComponent.getWidth(), trackComponent.getHeight()); } /** * In the case of an arrow border the track component lets us track the position * to which the border is pointing * @param trackComponent the track component */ public void setTrackComponent(Rectangle trackComponent) { this.trackComponent = trackComponent; } /** * This method is designed mainly for the purpose of creating an arrow that will track a specific component using the image border * the tile given would be an arrow like image just like the ones used for the top/bottom/left/right images. This image would be positioned * so it points at the center of the track component * * @param tileTop an image that will replace one of the tiles on the top if the track component is there * @param tileBottom an image that will replace one of the tiles on the bottom if the track component is there * @param tileLeft an image that will replace one of the tiles on the left if the track component is there * @param tileRight an image that will replace one of the tiles on the right if the track component is there * @param trackComponent the component that will be tracked for the positioning of the tile */ public void setImageBorderSpecialTile(Image tileTop, Image tileBottom, Image tileLeft, Image tileRight, Rectangle trackComponent) { specialTile = new Image[] {tileTop, tileBottom, tileLeft, tileRight}; this.trackComponent = trackComponent; } /** * Cleans the tile tracking state allowing the garbage collector to pick up the component and the image data */ public void clearImageBorderSpecialTile() { specialTile = null; trackComponent = null; } /** * Ads a border that wraps this border * * @param outer The outer border */ public void addOuterBorder(Border outer) { outerBorder=outer; } /** * Returns the minimum size required to properly display this border, normally this * is 0 but a border might deem itself undisplayable with too small a size e.g. for * the case of an image border the minimum height would be top + bottom and the minimum * width would be left+right * * @return 0 if not applicable or a dimension if it is. */ public int getMinimumHeight() { if(images != null) { if(images.length < 4) { if(type == TYPE_IMAGE_HORIZONTAL) { return images[0].getHeight(); } else { return images[0].getHeight() + images[1].getHeight(); } } Image topLeft = images[4]; Image bottomRight = images[7]; return topLeft.getHeight() + bottomRight.getHeight(); } return 0; } /** * Returns the minimum size required to properly display this border, normally this * is 0 but a border might deem itself undisplayable with too small a size e.g. for * the case of an image border the minimum height would be top + bottom and the minimum * width would be left+right * * @return 0 if not applicable or a dimension if it is. */ public int getMinimumWidth() { if(images != null) { if(images.length < 4) { if(type == TYPE_IMAGE_HORIZONTAL) { return images[0].getWidth() + images[1].getWidth(); } else { return images[0].getWidth(); } } Image topLeft = images[4]; Image topRight = images[5]; return topLeft.getWidth() + topRight.getWidth(); } return 0; } /** * Returns an empty border, this is mostly useful for overriding components that * have a border by default * * @return a border than draws nothing * @deprecated use createEmpty instead */ public static Border getEmpty() { if(empty == null) { empty = new Border(); } return empty; } /** * Creates an empty border, this is useful where we don't want a border for a * component but want a focus border etc... * * @return a border than draws nothing */ public static Border createEmpty() { Border b = new Border(); b.emptyType = true; return b; } /** * Indicates whether this is an empty border * @return true if this is an empty border */ public boolean isEmptyBorder() { return emptyType; } /** * The given top/bottom/left/right images are tiled appropriately across the matching sides of the border and the corners are placed * as expected in the four corners. The background image is optional and it will be tiled in the background if necessary. * *

By default this border does not override background unless a background image is specified * * @param top the image of the top line * @param bottom the image of the bottom line * @param left the image of the left line * @param right the image of the right line * @param topLeft the image of the top left corner * @param topRight the image of the top right corner * @param bottomLeft the image of the bottom left corner * @param bottomRight the image of the bottom right corner * @param background the image of the background (optional) * @return new border instance */ public static Border createImageBorder(Image top, Image bottom, Image left, Image right, Image topLeft, Image topRight, Image bottomLeft, Image bottomRight, Image background) { Border b = new Border(); b.type = TYPE_IMAGE; b.images = new Image[] {top, bottom, left, right, topLeft, topRight, bottomLeft, bottomRight, background}; return b; } /** * The given image is spliced into 9 pieces based on the provided top, right, bottom, and left insets, and the resulting * sub-images are used to form a 9-piece image border via {@link #createImageBorder(com.codename1.ui.Image, com.codename1.ui.Image, com.codename1.ui.Image, com.codename1.ui.Image, com.codename1.ui.Image, com.codename1.ui.Image, com.codename1.ui.Image, com.codename1.ui.Image, com.codename1.ui.Image) } * *

Insets are all given in a (u,v) coordinate space where (0,0) is the top-left corner of the image, and (1.0, 1.0) is the bottom-right corner of the image.

* @param img The image to be used as a background image and spliced. * @param topInset * @param rightInset * @param bottomInset * @param leftInset * @return A 9-piece image border. */ public static Border createImageSplicedBorder(Image img, double topInset, double rightInset, double bottomInset, double leftInset) { Border b = new Border(); b.type = TYPE_IMAGE; int w = img.getWidth(); int h = img.getHeight(); int topInsetPx = (int)Math.round(h * topInset); int leftInsetPx = (int)Math.round(w * leftInset); int rightInsetPx = (int)Math.round(w * rightInset); int bottomInsetPx = (int)Math.round(h * bottomInset); //We need to make sure that every splice has a positive width and height if (topInsetPx + bottomInsetPx >= h) { bottomInsetPx = h - topInsetPx -1; if (bottomInsetPx < 1) { bottomInsetPx = 1; topInsetPx = h - bottomInsetPx - 1; } } if (leftInsetPx + rightInsetPx >= w) { rightInsetPx = w - leftInsetPx - 1; if (rightInsetPx < 1) { rightInsetPx = 1; leftInsetPx = w - rightInsetPx - 1; } } Image top = img.subImage(leftInsetPx, 0, w - leftInsetPx - rightInsetPx, topInsetPx, true); Image bottom = img.subImage(leftInsetPx, h - bottomInsetPx, w - leftInsetPx - rightInsetPx, bottomInsetPx, true); Image left = img.subImage(0, topInsetPx, leftInsetPx, h - topInsetPx - bottomInsetPx, true); Image right = img.subImage(w - rightInsetPx, topInsetPx, rightInsetPx, h - topInsetPx - bottomInsetPx, true); Image topLeft = img.subImage(0, 0, leftInsetPx, topInsetPx, true); Image topRight = img.subImage(w - rightInsetPx, 0, rightInsetPx, topInsetPx, true); Image bottomLeft = img.subImage(0, h - bottomInsetPx, leftInsetPx, bottomInsetPx, true); Image bottomRight = img.subImage(w - rightInsetPx, h - bottomInsetPx, rightInsetPx, bottomInsetPx, true); Image background = img.subImage(leftInsetPx, topInsetPx, w - leftInsetPx - rightInsetPx, h - topInsetPx - bottomInsetPx, true); b.images = new Image[] {top, bottom, left, right, topLeft, topRight, bottomLeft, bottomRight, background}; return b; } /** * The given top/bottom/left/right images are scaled appropriately across the matching sides of the border and the corners are placed * as expected in the four corners. The background image is optional and it will be tiled in the background if necessary. * *

By default this border does not override background unless a background image is specified * * @param top the image of the top line * @param bottom the image of the bottom line * @param left the image of the left line * @param right the image of the right line * @param topLeft the image of the top left corner * @param topRight the image of the top right corner * @param bottomLeft the image of the bottom left corner * @param bottomRight the image of the bottom right corner * @param background the image of the background (optional) * @return new border instance */ public static Border createImageScaledBorder(Image top, Image bottom, Image left, Image right, Image topLeft, Image topRight, Image bottomLeft, Image bottomRight, Image background) { Border b = new Border(); b.type = TYPE_IMAGE_SCALED; b.images = new Image[] {top, bottom, left, right, topLeft, topRight, bottomLeft, bottomRight, background}; return b; } /** * This is an image border that can only grow horizontally * * @param left the image of the left side * @param right the image of the right side * @param center the image of the center * @return new border instance */ public static Border createHorizonalImageBorder(Image left, Image right, Image center) { Border b = new Border(); b.type = TYPE_IMAGE_HORIZONTAL; b.images = new Image[] {left, right, center}; return b; } /** * This is an image border that can only grow vertically * * @param top the image of the top * @param bottom the image of the bottom * @param center the image of the center * @return new border instance */ public static Border createVerticalImageBorder(Image top, Image bottom, Image center) { Border b = new Border(); b.type = TYPE_IMAGE_VERTICAL; b.images = new Image[] {top, bottom, center}; return b; } /** * The given images are tiled appropriately across the matching side of the border, rotated and placed * as expected in the four corners. The background image is optional and it will be tiled in * the background if necessary. *

By default this border does not override background unless a background image is specified. *

Notice that this version of the method is potentially much more efficient since images * are rotated internally and this might save quite a bit of memory! *

The top and topLeft images must be square! The width and height of these images * must be equal otherwise rotation won't work as you expect. * * @param top the image of the top line * @param topLeft the image of the top left corner * @param background the image of the background (optional) * @return new border instance */ public static Border createImageBorder(Image top, Image topLeft, Image background) { Border b = new Border(); b.type = TYPE_IMAGE; b.images = new Image[] {top, top.rotate(180), top.rotate(270), top.rotate(90), topLeft, topLeft.rotate(90), topLeft.rotate(270), topLeft.rotate(180), background}; return b; } /** * Creates a line border that uses the color of the component foreground for drawing * * @param thickness thickness of the border in pixels * @return new border instance */ public static Border createLineBorder(int thickness) { Border b = new Border(); b.type = TYPE_LINE; b.themeColors = true; b.thickness = thickness; b.millimeters = false; return b; } /** * Creates a line border that uses the color of the component foreground for drawing * * @param thickness thickness of the border in millimeters * @return new border instance */ public static Border createLineBorder(float thickness) { Border b = new Border(); b.type = TYPE_LINE; b.themeColors = true; b.thickness = thickness; b.millimeters = true; return b; } /** * Creates an underline border that uses the color of the component foreground for drawing * * @deprecated due to a spelling mistake. Use {@link #createUnderlineBorder(int thickness)} * @param thickness thickness of the border in pixels * @return new border instance */ public static Border createUndelineBorder(int thickness) { Border b = new Border(); b.type = TYPE_UNDERLINE; b.themeColors = true; b.thickness = thickness; return b; } /** * Creates an underline border that uses the color of the component foreground for drawing * * @param thickness thickness of the border in pixels * @return new border instance */ public static Border createUnderlineBorder(int thickness) { Border b = new Border(); b.type = TYPE_UNDERLINE; b.themeColors = true; b.thickness = thickness; return b; } /** * Creates an underline border that uses the color of the component foreground for drawing * * @deprecated due to a spelling mistake. Use {@link #createUnderlineBorder(float thickness)} * @param thickness thickness of the border in millimeters * @return new border instance */ public static Border createUndelineBorder(float thickness) { Border b = new Border(); b.type = TYPE_UNDERLINE; b.themeColors = true; b.thickness = thickness; b.millimeters = true; return b; } /** * Creates an underline border that uses the color of the component foreground for drawing * * @param thickness thickness of the border in millimeters * @return new border instance */ public static Border createUnderlineBorder(float thickness) { Border b = new Border(); b.type = TYPE_UNDERLINE; b.themeColors = true; b.thickness = thickness; b.millimeters = true; return b; } /** * Creates an underline border that uses the given color * * @param thickness thickness of the border in pixels * @param color the color * @return new border instance */ public static Border createUnderlineBorder(int thickness, int color) { Border b = new Border(); b.type = TYPE_UNDERLINE; b.themeColors = false; b.thickness = thickness; b.colorA = color; return b; } /** * Creates an underline border that uses the given color * * @param thickness thickness of the border in millimeters * @param color the color * @return new border instance */ public static Border createUnderlineBorder(float thickness, int color) { Border b = new Border(); b.type = TYPE_UNDERLINE; b.themeColors = false; b.thickness = thickness; b.millimeters = true; b.colorA = color; return b; } /** * Creates a dotted border with the specified thickness and color * * @param thickness The border thickness in pixels * @param color The border color * @return The border */ public static Border createDottedBorder(int thickness,int color) { return createCSSBorder(TYPE_DOTTED, thickness, color); } /** * Creates a dashed border with the specified thickness and color * * @param thickness The border thickness in pixels * @param color The border color * @return The border */ public static Border createDashedBorder(int thickness,int color) { return createCSSBorder(TYPE_DASHED, thickness, color); } /** * Creates a double border with the specified thickness and color * * @param thickness The border thickness in pixels * @param color The border color * @return The border */ public static Border createDoubleBorder(int thickness,int color) { return createCSSBorder(TYPE_DOUBLE, thickness, color); } /** * Creates a dotted border with the specified thickness and the theme colors * * @param thickness The border thickness in pixels * @return The border */ public static Border createDottedBorder(int thickness) { return createCSSBorder(TYPE_DOTTED, thickness); } /** * Creates a dashed border with the specified thickness and the theme colors * * @param thickness The border thickness in pixels * @return The border */ public static Border createDashedBorder(int thickness) { return createCSSBorder(TYPE_DASHED, thickness); } /** * Creates a double border with the specified thickness and color * * @param thickness The border thickness in pixels * @return The border */ public static Border createDoubleBorder(int thickness) { return createCSSBorder(TYPE_DOUBLE, thickness); } /** * Creates an outset border with the specified thickness and theme colors * * @param thickness The border thickness in pixels * @return The border */ public static Border createOutsetBorder(int thickness) { return createCSSBorder(TYPE_OUTSET, thickness); } /** * Creates an outset border with the specified thickness and color * * @param thickness The border thickness in pixels * @param color The border color * @return The border */ public static Border createOutsetBorder(int thickness,int color) { return createCSSBorder(TYPE_OUTSET, thickness,color); } /** * Creates an inset border with the specified thickness and theme colors * * @param thickness The border thickness in pixels * @return The border */ public static Border createInsetBorder(int thickness) { return createCSSBorder(TYPE_INSET, thickness); } /** * Creates an inset border with the specified thickness and color * * @param thickness The border thickness in pixels * @param color The border color * @return The border */ public static Border createInsetBorder(int thickness,int color) { return createCSSBorder(TYPE_INSET, thickness,color); } /** * Creates a groove border with the specified thickness and theme colors * * @param thickness The border thickness in pixels * @return The border */ public static Border createGrooveBorder(int thickness) { return createCSSBorder(TYPE_GROOVE, thickness); } /** * Creates a groove border with the specified thickness and color * * @param thickness The border thickness in pixels * @param color The border color * @return The border */ public static Border createGrooveBorder(int thickness,int color) { return createCSSBorder(TYPE_GROOVE, thickness,color); } /** * Creates a ridge border with the specified thickness and theme colors * * @param thickness The border thickness in pixels * @return The border */ public static Border createRidgeBorder(int thickness) { return createCSSBorder(TYPE_RIDGE, thickness); } /** * Creates a ridge border with the specified thickness and color * * @param thickness The border thickness in pixels * @param color The border color * @return The border */ public static Border createRidgeBorder(int thickness,int color) { return createCSSBorder(TYPE_RIDGE, thickness,color); } private static Border createCSSBorder(int type,int thickness) { Border b = new Border(); b.type = type; b.themeColors = true; b.thickness = thickness; return b; } private static Border createCSSBorder(int type,int thickness,int color) { Border b = new Border(); b.type = type; b.colorA = color; b.thickness = thickness; return b; } /** * Creates a line border with the specified title * * @param thickness thickness of the border in pixels * @param title The borders title * @return new border instance */ public static Border createLineBorder(int thickness, String title) { Border b = new Border(); b.type = TYPE_LINE; b.themeColors = true; b.thickness = thickness; b.borderTitle=title; return b; } /** * Creates a line border that uses the given color for the component * * @param thickness thickness of the border in pixels * @param color the color for the border * @param title The borders title * @return new border instance */ public static Border createLineBorder(int thickness, int color, String title) { Border b = new Border(); b.type = TYPE_LINE; b.themeColors = false; b.thickness = thickness; b.colorA = color; b.borderTitle=title; return b; } /** * Creates a line border that uses the given color for the component * * @param thickness thickness of the border in pixels * @param color the color for the border * @return new border instance */ public static Border createLineBorder(int thickness, int color) { Border b = new Border(); b.type = TYPE_LINE; b.themeColors = false; b.thickness = thickness; b.colorA = color; return b; } /** * Creates a line border that uses the given color for the component * * @param thickness thickness of the border in millimeters * @param color the color for the border * @return new border instance */ public static Border createLineBorder(float thickness, int color) { Border b = new Border(); b.type = TYPE_LINE; b.themeColors = false; b.thickness = thickness; b.millimeters = true; b.colorA = color; return b; } /** * Creates a rounded corner border that uses the color of the component foreground for drawing. * Due to technical issues (lack of shaped clipping) performance and memory overhead of round * borders can be low if used with either a bgImage or translucency! *

This border overrides any painter used on the component and would ignor such a painter. * * @param arcWidth the horizontal diameter of the arc at the four corners. * @param arcHeight the vertical diameter of the arc at the four corners. * @return new border instance * @deprecated the performance of round rect borders is REALLY slow, we recommend people use image borders * which are faster, more portable and better looking */ public static Border createRoundBorder(int arcWidth, int arcHeight) { Border b = new Border(); b.type = TYPE_ROUNDED; b.themeColors = true; b.arcHeight = arcHeight; b.arcWidth = arcWidth; return b; } /** * Creates a rounded corner border that uses the color of the component foreground for drawing. * Due to technical issues (lack of shaped clipping) performance and memory overhead of round * borders can be low if used with either a bgImage or translucency! *

This border overrides any painter used on the component and would ignor such a painter. * * @param arcWidth the horizontal diameter of the arc at the four corners. * @param arcHeight the vertical diameter of the arc at the four corners. * @param outline whether the round rect border outline should be drawn * @return new border instance * @deprecated the performance of round rect borders is REALLY slow, we recommend people use image borders * which are faster, more portable and better looking */ public static Border createRoundBorder(int arcWidth, int arcHeight, boolean outline) { Border b = createRoundBorder(arcWidth, arcHeight); b.outline = outline; return b; } /** * Creates a rounded border that uses the given color for the component. * Due to technical issues (lack of shaped clipping) performance and memory overhead of round * borders can be low if used with either a bgImage or translucency! *

This border overrides any painter used on the component and would ignor such a painter. * * @param arcWidth the horizontal diameter of the arc at the four corners. * @param arcHeight the vertical diameter of the arc at the four corners. * @param color the color for the border * @return new border instance * @deprecated the performance of round rect borders is REALLY slow, we recommend people use image borders * which are faster, more portable and better looking */ public static Border createRoundBorder(int arcWidth, int arcHeight, int color) { Border b = new Border(); b.type = TYPE_ROUNDED; b.themeColors = false; b.colorA = color; b.arcHeight = arcHeight; b.arcWidth = arcWidth; return b; } /** * Creates a rounded border that uses the given color for the component. * Due to technical issues (lack of shaped clipping) performance and memory overhead of round * borders can be low if used with either a bgImage or translucency! *

This border overrides any painter used on the component and would ignor such a painter. * * @param arcWidth the horizontal diameter of the arc at the four corners. * @param arcHeight the vertical diameter of the arc at the four corners. * @param color the color for the border * @param outline whether the round rect border outline should be drawn * @return new border instance * @deprecated the performance of round rect borders is REALLY slow, we recommend people use image borders * which are faster, more portable and better looking */ public static Border createRoundBorder(int arcWidth, int arcHeight, int color, boolean outline) { Border b = createRoundBorder(arcWidth, arcHeight, color); b.outline = outline; return b; } /** * Creates a lowered etched border with default colors, highlight is derived * from the component and shadow is a plain dark color * * @return new border instance */ public static Border createEtchedLowered() { Border b = new Border(); b.type = TYPE_ETCHED_LOWERED; b.themeColors = true; return b; } /** * Creates a raised etched border with the given colors * * @param highlight color RGB value * @param shadow color RGB value * @return new border instance */ public static Border createEtchedLowered(int highlight, int shadow) { Border b = new Border(); b.type = TYPE_ETCHED_LOWERED; b.themeColors = false; b.colorA = shadow; b.colorB = highlight; return b; } /** * Creates a lowered etched border with default colors, highlight is derived * from the component and shadow is a plain dark color * * @return new border instance */ public static Border createEtchedRaised() { Border b = new Border(); b.type = TYPE_ETCHED_RAISED; b.themeColors = true; b.thickness = 2; return b; } /** * Creates a raised etched border with the given colors * * @param highlight color RGB value * @param shadow color RGB value * @return new border instance */ public static Border createEtchedRaised(int highlight, int shadow) { Border b = new Border(); b.type = TYPE_ETCHED_RAISED; b.themeColors = false; b.colorA = highlight; b.colorB = shadow; b.thickness = 2; return b; } /** * {{@inheritDoc}} */ public boolean equals(Object obj) { if (obj != null && obj.getClass() == getClass()) { Border b = (Border)obj; if ((b.type==TYPE_COMPOUND) && (type==TYPE_COMPOUND)) { for(int i=Component.TOP;i<=Component.RIGHT;i++) { if (!isSame(compoundBorders[i], b.compoundBorders[i])) { return false; } } return true; } boolean v = ((themeColors==b.themeColors) && (type==b.type) && (thickness==b.thickness) && (colorA==b.colorA) && (colorB==b.colorB) && (colorC==b.colorC) && (colorD==b.colorD) && (arcWidth==b.arcWidth) && (arcHeight==b.arcHeight) && (outline==b.outline) && (isSame(borderTitle, b.borderTitle)) && (isSame(outerBorder, b.outerBorder)) ); if(v && (type == TYPE_IMAGE || type == TYPE_IMAGE_HORIZONTAL || type == TYPE_IMAGE_VERTICAL || type == TYPE_IMAGE_SCALED)) { int ilen = images.length; for(int iter = 0 ; iter < ilen ; iter++) { if(images[iter] != b.images[iter]) { return false; } } } return v; } return false; } /** * Compares two object including the scenario one of them is null (thus avoiding equals pitfalls) * * @param obj1 The first object to compare * @param obj2 The second object to compare * @return true if the two object are equal (or both null), false otherwise */ private static boolean isSame(Object obj1,Object obj2) { if (obj1==null) { return (obj2==null); } else if (obj2==null) { return (obj1==null); } return obj1.equals(obj2); } /** * Creates a border that is comprised of multiple border types so one border type can be used on top * while another one can be used at the bottom. Notice that this doesn't work well with all border types (e.g. image borders) * @param top the top border * @param bottom the bottom border * @param left the left border * @param right the right border * @return a compound border */ public static Border createCompoundBorder(Border top, Border bottom, Border left, Border right) { if ((top != null && !top.isRectangleType()) || (bottom != null && !bottom.isRectangleType()) || (left != null && !left.isRectangleType()) || (right != null && !right.isRectangleType())) { throw new IllegalArgumentException("Compound Border can be created " + "only from Rectangle types Borders"); } if ((isSame(top, bottom)) && (isSame(top, left)) && (isSame(top, right))) { return top; // Borders are all the same, returning one of them instead of creating a compound border which is more resource consuming } Border b = new Border(); b.type = TYPE_COMPOUND; b.compoundBorders = new Border[4]; b.compoundBorders[Component.TOP] = top; b.compoundBorders[Component.BOTTOM] = bottom; b.compoundBorders[Component.LEFT] = left; b.compoundBorders[Component.RIGHT] = right; // Calculates the thickness of the entire border as the maximum of all 4 sides b.thickness=0; for(int i=Component.TOP;i<=Component.RIGHT;i++) { if (b.compoundBorders[i]!=null) { int sideThickness = (int)b.compoundBorders[i].thickness; if (sideThickness>b.thickness) { b.thickness=sideThickness; } } } return b; } /** * Returns true if installing this border will override the painting of the component background * * @return true if this border replaces the painter */ public boolean isBackgroundPainter() { return type == TYPE_ROUNDED || type == TYPE_ROUNDED_PRESSED || type == TYPE_IMAGE || type == TYPE_IMAGE_HORIZONTAL || type == TYPE_IMAGE_VERTICAL || type == TYPE_IMAGE_SCALED; } /** * Returns true if this border type is a rectangle border. * * @return true if this border is rectangle */ public boolean isRectangleType() { return type == TYPE_LINE || type == TYPE_BEVEL_LOWERED || type == TYPE_BEVEL_RAISED || type == TYPE_ETCHED_LOWERED || type == TYPE_ETCHED_RAISED || type == TYPE_COMPOUND || type == TYPE_EMPTY || type==TYPE_DOTTED || type==TYPE_DASHED || type==TYPE_DOUBLE || type == TYPE_OUTSET || type == TYPE_INSET || type == TYPE_GROOVE || type == TYPE_RIDGE; } /** * Creates a lowered bevel border with default colors, highlight is derived * from the component and shadow is a plain dark color * * @return new border instance */ public static Border createBevelLowered() { Border b = new Border(); b.type = TYPE_BEVEL_LOWERED; b.themeColors = true; b.thickness = 2; return b; } /** * Creates a raised bevel border with the given colors * * @param highlightOuter RGB of the outer edge of the highlight area * @param highlightInner RGB of the inner edge of the highlight area * @param shadowOuter RGB of the outer edge of the shadow area * @param shadowInner RGB of the inner edge of the shadow area * @return new border instance */ public static Border createBevelLowered(int highlightOuter, int highlightInner, int shadowOuter, int shadowInner) { Border b = new Border(); b.type = TYPE_BEVEL_LOWERED; b.themeColors = false; b.colorA = highlightOuter; b.colorB = highlightInner; b.colorC = shadowOuter; b.colorD = shadowInner; b.thickness = 2; return b; } /** * Creates a lowered bevel border with default colors, highlight is derived * from the component and shadow is a plain dark color * * @return new border instance */ public static Border createBevelRaised() { Border b = new Border(); b.type = TYPE_BEVEL_RAISED; b.themeColors = true; b.thickness = 2; return b; } /** * Creates a raised bevel border with the given colors * * @param highlightOuter RGB of the outer edge of the highlight area * @param highlightInner RGB of the inner edge of the highlight area * @param shadowOuter RGB of the outer edge of the shadow area * @param shadowInner RGB of the inner edge of the shadow area * @return new border instance */ public static Border createBevelRaised(int highlightOuter, int highlightInner, int shadowOuter, int shadowInner) { Border b = new Border(); b.type = TYPE_BEVEL_RAISED; b.themeColors = false; b.colorA = highlightOuter; b.colorB = highlightInner; b.colorC = shadowOuter; b.colorD = shadowInner; b.thickness = 2; return b; } /** * Allows us to define a border that will act as the pressed version of this border * * @param pressed a border that will be returned by the pressed version method */ public void setPressedInstance(Border pressed) { pressedBorder = pressed; } /** * Allows us to define a border that will act as the focused version of this border * * @param focused a border that will be returned by the focused version method * @deprecated use the getSelectedStyle() method in the component class */ public void setFocusedInstance(Border focused) { focusBorder = focused; } /** * Returns the focused version of the border if one is installed * * @return a focused version of this border if one exists * @deprecated use the getSelectedStyle() method in the component class */ public Border getFocusedInstance() { if(focusBorder != null) { return focusBorder; } return this; } /** * Returns the pressed version of the border if one is set by the user * * @return the pressed instance of this border */ public Border getPressedInstance() { if(pressedBorder != null) { return pressedBorder; } return this; } /** * When applied to buttons borders produce a version that reverses the effects * of the border providing a pressed feel * * @return a border that will make the button feel pressed */ public Border createPressedVersion() { if(pressedBorder != null) { return pressedBorder; } switch(type) { case TYPE_LINE: if(millimeters) { return createLineBorder(thickness + 0.1f, colorA); } return createLineBorder((int)thickness + 1, colorA); case TYPE_ETCHED_LOWERED: { Border b = createEtchedRaised(colorA, colorB); b.themeColors = themeColors; return b; } case TYPE_ETCHED_RAISED: { Border b = createEtchedLowered(colorA, colorB); b.themeColors = themeColors; return b; } case TYPE_BEVEL_RAISED: { Border b = createBevelLowered(colorA, colorB, colorC, colorD); b.themeColors = themeColors; return b; } case TYPE_BEVEL_LOWERED: { Border b = createBevelRaised(colorA, colorB, colorC, colorD); b.themeColors = themeColors; return b; } case TYPE_ROUNDED: { Border b = createRoundBorder(arcWidth, arcHeight, colorA); b.themeColors = themeColors; b.type = TYPE_ROUNDED_PRESSED; return b; } case TYPE_ROUNDED_PRESSED: { Border b = createRoundBorder(arcWidth, arcHeight, colorA); b.themeColors = themeColors; return b; } } return this; } /** * Has effect when the border demands responsibility for background painting * normally the painter will perform this work but in this case the border might * do it instead. * * @param g graphics context to draw onto * @param c component whose border should be drawn */ public void paintBorderBackground(Graphics g, Component c) { int x = c.getX(); int y = c.getY(); int width = c.getWidth(); int height = c.getHeight(); if (outerBorder != null) { int ac; if(millimeters) { ac = Display.getInstance().convertToPixels(thickness); } else { ac = (int)thickness; } if (paintOuterBorderFirst) { outerBorder.paintBorderBackground(g, c); paintBorderBackground(g, x + ac, y + ac, width - ac * 2, height - ac * 2, c); } else { paintBorderBackground(g, x + ac, y + ac, width - ac * 2, height - ac * 2, c); outerBorder.paintBorderBackground(g, c); } } else { paintBorderBackground(g, x, y, width, height, c); } } private void setClipScaled(Graphics g, int x, int y, int w, int h) { if(g.getScaleX() < 1) { w = (int)(((float)w) / g.getScaleX()); } if(g.getScaleY() < 1) { h = (int)(((float)h) / g.getScaleY()); } g.setClip(x, y, w, h); } private void paintBorderBackground(Graphics g, final int xParameter, final int yParameter, final int widthParameter, final int heightParameter, Component c) { int originalColor = g.getColor(); int x = xParameter; int y = yParameter; int width = widthParameter; int height = heightParameter; switch(type) { case TYPE_ROUNDED_PRESSED: x++; y++; width -= 2; height -= 2; case TYPE_ROUNDED: // Removing this due to issue 301, not sure regarding this... //width--; //height--; // rounded is also responsible for drawing the background Style s = c.getStyle(); if((s.getBgImage() != null && s.getBackgroundType() == Style.BACKGROUND_IMAGE_SCALED) || s.getBackgroundType() > 1) { Object w = s.roundRectCache; Image i = null; if(w != null) { i = (Image)Display.getInstance().extractHardRef(w); } if(i != null && i.getWidth() == width && i.getHeight() == height) { g.drawImage(i, x, y); } else { // we need to draw a background image! i = ImageFactory.createImage(c, width, height, 0); Graphics imageG = i.getGraphics(); imageG.setColor(0); imageG.fillRoundRect(0, 0, width, height, arcWidth, arcHeight); int[] rgb = i.getRGBCached(); int transColor = rgb[0]; int[] imageRGB; if(s.getBackgroundType() == Style.BACKGROUND_IMAGE_SCALED) { imageRGB = s.getBgImage().scaled(width, height).getRGBCached(); } else { Image bgPaint = ImageFactory.createImage(c, width, height, 0); Painter p = s.getBgPainter(); // might occur during temporary conditions in the theme switching if(p == null) { return; } p.paint(bgPaint.getGraphics(), new Rectangle(0, 0, width, height)); imageRGB = bgPaint.getRGB(); } int rlen = rgb.length; for(int iter = 0 ; iter < rlen ; iter++) { if(rgb[iter] == transColor) { imageRGB[iter] = 0; } } i = Image.createImage(imageRGB, width, height); s.roundRectCache = Display.getInstance().createSoftWeakRef(i); g.drawImage(i, x, y); } } else { int foreground = g.getColor(); g.setColor(s.getBgColor()); // Its opaque much easier job! if(s.getBgTransparency() == ((byte)0xff)) { g.fillRoundRect(x, y , width, height, arcWidth, arcHeight); } else { if(g.isAlphaSupported()) { int alpha = g.getAlpha(); g.setAlpha(s.getBgTransparency() & 0xff); g.fillRoundRect(x, y , width, height, arcWidth, arcHeight); g.setAlpha(alpha); } else { // if its transparent we don't need to do anything, if its // translucent... well.... if(s.getBgTransparency() != 0) { Image i = ImageFactory.createImage(c, width, height, 0); int[] imageRgb; if(g.getColor() != 0xffffff) { Graphics imageG = i.getGraphics(); imageG.setColor(g.getColor()); imageG.fillRoundRect(0, 0 , width, height, arcWidth, arcHeight); imageRgb = i.getRGBCached(); } else { // background color is white we need to remove a different color // black is the only other "reliable" color on the device Graphics imageG = i.getGraphics(); imageG.setColor(0); imageG.fillRect(0, 0, width, height); imageG.setColor(g.getColor()); imageG.fillRoundRect(0, 0 , width, height, arcWidth, arcHeight); imageRgb = i.getRGBCached(); } int removeColor = imageRgb[0]; int size = width * height; int alphaInt = ((s.getBgTransparency() & 0xff) << 24) & 0xff000000; for(int iter = 0 ; iter < size ; iter++) { if(removeColor == imageRgb[iter]) { imageRgb[iter] = 0; continue; } if((imageRgb[iter] & 0xff000000) != 0) { imageRgb[iter] = (imageRgb[iter] & 0xffffff) | alphaInt; } } g.drawImage(new RGBImage(imageRgb, width, height), x, y); } } } g.setColor(foreground); } break; case TYPE_IMAGE: { Image topLeft = images[4]; Image topRight = images[5]; Image bottomLeft = images[6]; Image center = images[8]; x += topLeft.getWidth(); y += topLeft.getHeight(); height -= (topLeft.getHeight() + bottomLeft.getHeight()); width -= (topLeft.getWidth() + topRight.getWidth()); if(center != null){ g.tileImage(center, x, y, width, height); } Image top = images[0]; Image bottom = images[1]; Image left = images[2]; Image right = images[3]; Image bottomRight = images[7]; x = xParameter; y = yParameter; width = widthParameter; height = heightParameter; g.drawImage(topLeft, x, y); g.drawImage(bottomLeft, x, y + height - bottomLeft.getHeight()); g.drawImage(topRight, x + width - topRight.getWidth(), y); g.drawImage(bottomRight, x + width - bottomRight.getWidth(), y + height - bottomRight.getHeight()); Image arrowDownImage = null; Image arrowUpImage = null; Image arrowLeftImage = null; Image arrowRightImage = null; int arrowPosition = 0; // we need to draw an arrow on one of the sides if(trackComponent != null && specialTile != null) { int cabsY = c.getAbsoluteY(); int trackY = trackComponent.getY(); int trackX = trackComponent.getX(); int cabsX = c.getAbsoluteX(); if(cabsY >= trackY + trackComponent.getHeight()) { // we are below the component arrowUpImage = specialTile[0]; arrowPosition = (trackX + trackComponent.getWidth() / 2) - cabsX - arrowUpImage.getWidth() / 2; } else { if(cabsY + c.getHeight() <= trackY) { // we are above the component arrowDownImage = specialTile[1]; arrowPosition = (trackX + trackComponent.getWidth() / 2) - cabsX - arrowDownImage.getWidth() / 2; } else { if(cabsX >= trackX + trackComponent.getWidth()) { // we are to the right of the component arrowLeftImage = specialTile[2]; arrowPosition = (trackY + trackComponent.getHeight() / 2) - cabsY - arrowLeftImage.getHeight() / 2; } else { if(cabsX + c.getWidth() <= trackX) { // we are to the left of the component arrowRightImage = specialTile[3]; arrowPosition = (trackY + trackComponent.getHeight() / 2) - cabsY - arrowRightImage.getHeight() / 2; } } } } } drawImageBorderLine(g, topLeft, topRight, top, x, y, width, arrowUpImage, arrowPosition, false); drawImageBorderLine(g, bottomLeft, bottomRight, bottom, x, y + height - bottom.getHeight(), width, arrowDownImage, arrowPosition, true); drawImageBorderColumn(g, topLeft, bottomLeft, left, x, y, height, arrowLeftImage, arrowPosition, false); drawImageBorderColumn(g, topRight, bottomRight, right, x + width - right.getWidth(), y, height, arrowRightImage, arrowPosition, true); break; } case TYPE_IMAGE_SCALED: { int clipX = g.getClipX(); int clipY = g.getClipY(); int clipWidth = g.getClipWidth(); int clipHeight = g.getClipHeight(); //g.pushClip(); Image topLeft = images[4]; Image topRight = images[5]; Image bottomLeft = images[6]; Image center = images[8]; x += topLeft.getWidth(); y += topLeft.getHeight(); height -= (topLeft.getHeight() + bottomLeft.getHeight()); width -= (topLeft.getWidth() + topRight.getWidth()); g.clipRect(x, y, width, height); if(center != null && width > 0 && height > 0){ int centerWidth = center.getWidth(); int centerHeight = center.getHeight(); g.drawImage(center, x, y, width, height); } Image top = images[0]; Image bottom = images[1]; Image left = images[2]; Image right = images[3]; Image bottomRight = images[7]; g.setClip(clipX, clipY, clipWidth, clipHeight); //g.popClip(); //g.pushClip(); x = xParameter; y = yParameter; width = widthParameter; height = heightParameter; g.drawImage(topLeft, x, y); g.drawImage(bottomLeft, x, y + height - bottomLeft.getHeight()); g.drawImage(topRight, x + width - topRight.getWidth(), y); g.drawImage(bottomRight, x + width - bottomRight.getWidth(), y + height - bottomRight.getHeight()); drawImageBorderLineScale(g, topLeft, topRight, top, x, y, width); drawImageBorderLineScale(g, bottomLeft, bottomRight, bottom, x, y + height - bottom.getHeight(), width); drawImageBorderColumnScale(g, topLeft, bottomLeft, left, x, y, height); drawImageBorderColumnScale(g, topRight, bottomRight, right, x + width - right.getWidth(), y, height); g.setClip(clipX, clipY, clipWidth, clipHeight); //g.popClip(); break; } case TYPE_IMAGE_HORIZONTAL: { Image left = images[0]; Image right = images[1]; Image center = images[2]; Boolean centerAlignHBorderBool = c == null ? null : (Boolean)c.getClientProperty("@centerAlignHBorderBool"); boolean b = centerAlignHBorderBool == null ? false : centerAlignHBorderBool; if(b || c.getUIManager().isThemeConstant("centerAlignHBorderBool", false)) { y += Math.max(0, height / 2 - center.getHeight() / 2); } g.drawImage(left, x, y); g.drawImage(right, x + width - right.getWidth(), y); g.tileImage(center, x + left.getWidth(), y, width - left.getWidth() - right.getWidth(), center.getHeight()); break; } case TYPE_IMAGE_VERTICAL: { Image top = images[0]; Image bottom = images[1]; Image center = images[2]; g.drawImage(top, x, y); g.drawImage(bottom, x, y + height - bottom.getHeight()); g.tileImage(center, x, y + top.getHeight(), center.getWidth(), height - top.getHeight() - bottom.getHeight()); break; } } g.setColor(originalColor); } /** * Draws the border for the given component, this method is called before a call to * background painting is made. * * @param g graphics context to draw onto * @param c component whose border should be drawn */ public void paint(Graphics g, Component c) { int x = c.getX(); int y = c.getY(); int width = c.getWidth(); int height = c.getHeight(); if (outerBorder!=null) { int ac; if(millimeters) { ac = Display.getInstance().convertToPixels(thickness); } else { ac = (int)thickness; } if(paintOuterBorderFirst) { outerBorder.paint(g, x, y, width, height, c); paint(g, x+ac, y+ac, width-ac*2, height-ac*2, c); } else { paint(g, x+ac, y+ac, width-ac*2, height-ac*2, c); outerBorder.paint(g, x, y, width, height, c); } } else { paint(g, x, y, width, height, c); } } void paint(Graphics g,int x,int y,int width,int height,Component c) { int originalColor = g.getColor(); if(!themeColors) { g.setColor(colorA); } int ac = 1; if(thickness > 0) { if(millimeters) { ac = Display.getInstance().convertToPixels(thickness); } else { ac = (int)thickness; } } switch(type) { case TYPE_LINE: if (borderTitle==null) { if(millimeters) { g.drawRect(x, y, width, height, ac); } else { g.drawRect(x, y, width, height, ac); } } else { Font f=c.getStyle().getFont(); int titleW=f.stringWidth(borderTitle); int topPad=c.getStyle().getPaddingTop(); int topY=y+(topPad-ac)/2; if (c.isRTL()) { g.fillRect(x+width-TITLE_MARGIN, topY, TITLE_MARGIN , ac); //top (segment before the title) g.fillRect(x, topY, width-(TITLE_MARGIN +titleW+TITLE_SPACE*2), ac); //top (segment after the title) g.drawString(borderTitle, x+width-(TITLE_MARGIN +titleW+TITLE_SPACE), y+(topPad-f.getHeight())/2); } else { g.fillRect(x, topY, TITLE_MARGIN , ac); //top (segment before the title) g.fillRect(x+TITLE_MARGIN +titleW+TITLE_SPACE*2, topY, width-(TITLE_MARGIN +titleW+TITLE_SPACE*2), ac); //top (segment after the title) g.drawString(borderTitle, x+TITLE_MARGIN+TITLE_SPACE, y+(topPad-f.getHeight())/2); } g.fillRect(x, y+height-ac, width, ac); //bottom g.fillRect(x, topY, ac, height); //left g.fillRect(x+width-ac, topY, ac, height); //right } break; case TYPE_DASHED: case TYPE_DOTTED: int segWidth=ac; if (type==TYPE_DASHED) { segWidth=ac*3; } int ix=x; for (;ix=66)) { g.drawRect(x + iter, y + iter, width, height); } width -= 2; height -= 2; } break; case TYPE_INSET: case TYPE_OUTSET: for(int i=0;i 0) { g.tileImage(center, x + left.getWidth(), y, width - right.getWidth() - left.getWidth(), center.getHeight()); if(arrow != null) { imagePosition = Math.max(imagePosition, left.getWidth()); imagePosition = Math.min(imagePosition, width - arrow.getWidth() - right.getWidth()); if(farEdge) { g.drawImage(arrow, x + imagePosition, y + center.getHeight() - arrow.getHeight()); } else { g.drawImage(arrow, x + imagePosition, y); } } } } private void drawImageBorderColumn(Graphics g, Image top, Image bottom, Image center, int x, final int y, int height, Image arrow, int imagePosition, boolean farEdge) { if(height - bottom.getHeight() > 0) { g.tileImage(center, x, y + top.getHeight(), center.getWidth(), height - top.getHeight() - bottom.getHeight()); if(arrow != null) { imagePosition = Math.max(imagePosition, top.getHeight()); imagePosition = Math.min(imagePosition, height - arrow.getHeight() - bottom.getHeight()); if(farEdge) { g.drawImage(arrow, x + center.getWidth() - arrow.getWidth(), y + imagePosition); } else { g.drawImage(arrow, x, y + imagePosition); } } } } private void drawImageBorderLineScale(Graphics g, Image left, Image right, Image center, int x, int y, int width) { int currentWidth = width - right.getWidth() - left.getWidth(); if(currentWidth > 0) { x += left.getWidth(); g.drawImage(center, x, y, currentWidth, center.getHeight()); } } private void drawImageBorderColumnScale(Graphics g, Image top, Image bottom, Image center, int x, int y, int height) { int currentHeight = height - bottom.getHeight() - top.getHeight(); if(currentHeight > 0) { y += top.getHeight(); g.drawImage(center, x, y, center.getWidth(), currentHeight); } } /** * Sets the default border to the given value * * @param border new border value */ public static void setDefaultBorder(Border border) { defaultBorder = border; } /** * Gets the default border to the given value * * @return the default border */ public static Border getDefaultBorder() { return defaultBorder; } /** * This method returns how thick is the border in pixels, notice this doesn't apply to most border types * @return the Border thickness */ public int getThickness() { if(millimeters) { return Display.getInstance().convertToPixels(thickness); } return (int)thickness; } /** * This method returns sets the border thickness in pixels, notice this doesn't apply to most border types * @param thickness the Border thickness */ public void setThickness(int thickness) { this.thickness = thickness; } /** * Allows toggling the order in which the outer and inner borders are painted for the Outer border type * @param paintOuterBorderFirst whether the outside border should be painter first */ public void setPaintOuterBorderFirst(boolean paintOuterBorderFirst) { this.paintOuterBorderFirst = paintOuterBorderFirst; } /** * Allows toggling the order in which the outer and inner borders are painted for the Outer border type * @return whether the outside border should be painter first */ public boolean isPaintOuterBorderFirst() { return paintOuterBorderFirst; } /** * This method returns the Compound Borders array. * The array size is 4 and the borders arranged as follows : * Border[] borders = getCompoundBorders(); * Border top = borders[Component.TOP]; * Border bottom = borders[Component.BOTTOM]; * Border left = borders[Component.LEFT]; * Border right = borders[Component.RIGHT]; * * @return the borders array or null if this is not a Compound Border */ public Border[] getCompoundBorders() { return compoundBorders; } /** * This callback indicates that a component pointing at this border is initialized, this * method is useful for image borders whose lock methods are implicitly invoked. * This method may be invoked multiple times. */ public void lock() { if(images != null) { int ilen = images.length; for(int iter = 0 ; iter < ilen ; iter++) { if(images[iter] != null) { images[iter].lock(); } } } } /** * This callback indicates that a component pointing at this border is now deinitilized * This method may be invoked multiple times. */ public void unlock() { if(images != null) { int ilen = images.length; for(int iter = 0 ; iter < ilen ; iter++) { if(images[iter] != null) { images[iter].unlock(); } } } } /** * This method is for internal usage only! */ public Object getProperty(String n) { if(n.equals("ThemeColors")) { if(themeColors) { return Boolean.TRUE; } return Boolean.FALSE; } if(n.equals("Type")) { return new Integer(type); } if(n.equals("ColorA")) { return new Integer(colorA); } if(n.equals("ColorB")) { return new Integer(colorB); } if(n.equals("ColorC")) { return new Integer(colorC); } if(n.equals("ColorD")) { return new Integer(colorD); } if(n.equals("ArcWidth")) { return new Integer(arcWidth); } if(n.equals("ArcHeight")) { return new Integer(arcHeight); } if(n.equals("Images")) { return images; } return null; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy