下面列出了java.awt.geom.GeneralPath#lineTo ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
GeneralPath arrow = new GeneralPath();
int w, h;
h = (int) (2 * sizeFactor);
w = (int) (4 * sizeFactor);
arrow.moveTo(getWidth() / 2 - w, getHeight() / 2);
arrow.lineTo(getWidth() / 2 + w, getHeight() / 2);
arrow.lineTo(getWidth() / 2, getHeight() / 2 + 2 * h);
arrow.closePath();
if (isEnabled()) {
g.setColor(Color.BLACK);
} else {
g.setColor(Color.GRAY);
}
((Graphics2D) g).fill(arrow);
}
protected void fillAreaAndClip(GeneralPath path, double x, double startX, int yTo) {
GeneralPath pattern = new GeneralPath(path);
path.lineTo(x, yTo);
path.lineTo(startX, yTo);
path.closePath();
g2d.fill(path);
pattern.lineTo(x, yTo);
pattern.lineTo(xMax, yTo);
pattern.lineTo(xMax, yMin);
pattern.lineTo(xMin, yMin);
pattern.lineTo(xMin, yTo);
pattern.lineTo(startX, yTo);
pattern.lineTo(x, yTo);
pattern.lineTo(xMax, yTo);
pattern.lineTo(xMax, yMax);
pattern.lineTo(xMin, yMax);
pattern.lineTo(xMin, yTo);
pattern.lineTo(startX, yTo);
pattern.closePath();
g2d.clip(pattern);
}
/**
* Creates a diagonal cross shape.
*
* @param l the length of each 'arm'.
* @param t the thickness.
*
* @return A diagonal cross shape.
*/
public static Shape createRegularCross(float l, float t) {
GeneralPath p0 = new GeneralPath();
p0.moveTo(-l, t);
p0.lineTo(-t, t);
p0.lineTo(-t, l);
p0.lineTo(t, l);
p0.lineTo(t, t);
p0.lineTo(l, t);
p0.lineTo(l, -t);
p0.lineTo(t, -t);
p0.lineTo(t, -l);
p0.lineTo(-t, -l);
p0.lineTo(-t, -t);
p0.lineTo(-l, -t);
p0.closePath();
return p0;
}
/**
* Creates a diagonal cross shape.
*
* @param l the length of each 'arm'.
* @param t the thickness.
*
* @return A diagonal cross shape.
*/
public static Shape createDiagonalCross(final float l, final float t) {
final GeneralPath p0 = new GeneralPath();
p0.moveTo(-l - t, -l + t);
p0.lineTo(-l + t, -l - t);
p0.lineTo(0.0f, -t * SQRT2);
p0.lineTo(l - t, -l - t);
p0.lineTo(l + t, -l + t);
p0.lineTo(t * SQRT2, 0.0f);
p0.lineTo(l + t, l - t);
p0.lineTo(l - t, l + t);
p0.lineTo(0.0f, t * SQRT2);
p0.lineTo(-l + t, l + t);
p0.lineTo(-l - t, l - t);
p0.lineTo(-t * SQRT2, 0.0f);
p0.closePath();
return p0;
}
@Override
public Shape getRegiao() {
if (Regiao == null) {
final int v1 = getHeight() / 3;
final int h1 = getWidth() / 2;
final int repo = v1 / 3;
final int L = getLeft();
final int T = getTop();
final int TH = T + getHeight() - repo;
final int LW = L + getWidth();
CubicCurve2D c = new CubicCurve2D.Double();
c.setCurve(LW, TH, LW - h1, TH - v1, L + h1, TH + v1, L, TH);
CubicCurve2D c2 = new CubicCurve2D.Double();
int v2 = v1 / 3;
c2.setCurve(L, T + v2, L + h1, T + v1 + v2, LW - h1, T - v1 + v2, LW, T + v2);
GeneralPath pa = new GeneralPath();
pa.setWindingRule(GeneralPath.WIND_EVEN_ODD);
pa.append(c2, true);
pa.lineTo(LW, TH);
pa.append(c, true);
pa.lineTo(L, T + v2);
pa.closePath();
Regiao = pa;
int ptToMove = 3;
this.reposicionePonto[ptToMove] = new Point(0, -repo);
ptsToMove[ptToMove] = 1;
ptToMove = 1;
this.reposicionePonto[ptToMove] = new Point(0, repo);
ptsToMove[ptToMove] = 1;
}
return Regiao;
}
/**
* Draw arraw
*
* @param g Graphics2D
* @param sP Start point
* @param angle Angle
* @param size Arrow size
*/
public static void drawArraw(Graphics2D g, PointF sP, double angle, int size) {
GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 5);
Rectangle.Float rect = new Rectangle.Float(-size, -size, size * 2, size * 2);
PointF[] pt = new PointF[5];
pt[0] = new PointF(rect.x, rect.y);
pt[1] = new PointF(rect.x + rect.width, rect.y + (rect.height / 2));
pt[2] = new PointF(rect.x, rect.y + rect.height);
pt[3] = new PointF(rect.x + rect.width / 2, pt[1].Y);
pt[4] = pt[0];
path.moveTo(pt[0].X, pt[0].Y);
for (int i = 1; i < 5; i++) {
path.lineTo(pt[i].X, pt[i].Y);
}
AffineTransform tempTrans = g.getTransform();
if (angle != 0) {
//AffineTransform myTrans = new AffineTransform();
AffineTransform myTrans = (AffineTransform) tempTrans.clone();
//myTrans.translate(tempTrans.getTranslateX() + sP.X, tempTrans.getTranslateY() + sP.Y);
myTrans.translate(sP.X, sP.Y);
double angle1 = angle - 90;
myTrans.rotate(angle1 * Math.PI / 180);
g.setTransform(myTrans);
}
path.closePath();
g.fill(path);
if (angle != 0) {
g.setTransform(tempTrans);
}
}
/**
* Creates a triangle shape that points downwards.
*
* @param s the size factor (equal to half the height of the triangle).
*
* @return A triangle shape.
*/
public static Shape createDownTriangle(float s) {
GeneralPath p0 = new GeneralPath();
p0.moveTo(0.0f, s);
p0.lineTo(s, -s);
p0.lineTo(-s, -s);
p0.closePath();
return p0;
}
/**
* Draw the Polygon to the buffer of the given size.
*/
public void draw(Graphics2D g, int width, int height) {
g.setColor(new Color(data[0], data[1], data[2], data[3]));
GeneralPath path = new GeneralPath();
path.moveTo(data[4] * width, data[5] * height);
int polygonLength = (data.length - 4) / 2;
for (int j = 1; j < polygonLength; j++) {
path.lineTo(data[4 + j * 2] * width, data[5 + j * 2] * height);
}
path.closePath();
g.fill(path);
}
protected Shape createArrow(float fx, float fy, float tx, float ty) {
float dx = tx - fx;
float dy = ty - fy;
float D = (float) Math.sqrt(dx * dx + dy * dy);
float z = (dx <= 0) ? fx - D : fx + D;
double alpha = (dx > 0) ? Math.asin(dy / D) : -Math.asin(dy / D);
float h = arrowWidth * 2;
int n = (int) (D / h);
h = D / (float) (n + 1);
if (n < 0)
n = 0;
float dec = (dx <= 0) ? h : -h;
GeneralPath gp = new GeneralPath();
for (int i = 0; i <= n; i++) {
gp.moveTo(z + dec, fy - arrowWidth);
gp.lineTo(z + dec / 2f, fy - arrowWidth);
gp.lineTo(z, fy);
gp.lineTo(z + dec / 2f, fy + arrowWidth);
gp.lineTo(z + dec, fy + arrowWidth);
gp.lineTo(z + dec / 2f, fy);
z += dec;
}
gp.closePath();
AffineTransform affineTransform = new AffineTransform();
affineTransform.rotate(alpha, fx, fy);
return gp.createTransformedShape(affineTransform);
}
public void renderPreview(Graphics2D g2d) {
Point2D.Double s = new Point2D.Double(getXPos(), getYPos());
//store properties
Stroke before = g2d.getStroke();
Composite coBefore = g2d.getComposite();
Font fBefore = g2d.getFont();
AffineTransform tb = g2d.getTransform();
//start draw
g2d.setFont(fBefore.deriveFont((float) getTextSize()));
g2d.setStroke(getStroke());
g2d.setColor(drawColor);
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, drawAlpha));
path = new GeneralPath();
path.moveTo(getXPos(), getYPos() - 10);
path.lineTo(getXPos() + 80, getYPos() - 10);
path.lineTo(getXPos() + 80, getYPos() - 20);
path.lineTo(getXPos() + 100, getYPos());
path.lineTo(getXPos() + 80, getYPos() + 20);
path.lineTo(getXPos() + 80, getYPos() + 10);
path.lineTo(getXPos() + 0, getYPos() + 10);
path.closePath();
if (filled) {
g2d.fill(path);
} else {
g2d.draw(path);
}
if (drawName) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getTextAlpha()));
g2d.setColor(getTextColor());
g2d.drawString(getFormName(), (int) s.x, (int) s.y);
}
//reset properties
g2d.setStroke(before);
g2d.setComposite(coBefore);
g2d.setFont(fBefore);
g2d.setTransform(tb);
}
@Override
public void paintComponent(Graphics g) {
if (mainButton != null && mainButton.getModel().isArmed() || getModel().isArmed()) {
((Graphics2D) g).translate(1.1, 1.1);
}
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
// fill background white
g2.setColor(BACKGROUND_COLOR);
g2.fillRect(3, 0, getWidth() - 9, getHeight() - 6);
// draw border which complements the DropShadow
g2.setColor(BORDER_LIGHTEST_GRAY);
g2.drawLine(3, 0, 3, getHeight() - 6);
g2.drawLine(getWidth() - 6, 0, getWidth() - 6, getHeight() - 6);
g2.drawLine(3, getHeight() - 6, getWidth() - 6, getHeight() - 6);
g2.drawLine(3, 0, getWidth() - 6, 0);
// draw arrow
GeneralPath arrow = new GeneralPath();
int w, h;
h = (int) (2 * sizeFactor);
w = (int) (4 * sizeFactor);
arrow.moveTo(getWidth() / 2 - w, getHeight() / 2);
arrow.lineTo(getWidth() / 2 + w, getHeight() / 2);
arrow.lineTo(getWidth() / 2, getHeight() / 2 + 2 * h);
arrow.closePath();
if (isEnabled()) {
g2.setColor(HOVERED_TEXTCOLOR);
} else {
g2.setColor(BORDER_LIGHTEST_GRAY);
}
g2.fill(arrow);
g2.dispose();
}
public Shape getBorderBottomShape() {
if ( borderShapeBottom != null ) {
return borderShapeBottom;
}
final StaticBoxLayoutProperties sblp = this.staticBoxLayoutProperties;
final long halfBorderWidth = sblp.getBorderBottom() / 2;
final long x = this.x;
final long y = this.y;
final long w = this.width;
final long h = this.height;
final Border border = boxDefinition.getBorder();
final long bottomLeftWidth = border.getBottomLeft().getWidth();
final long bottomLeftHeight = border.getBottomLeft().getHeight();
final long bottomRightWidth = border.getBottomRight().getWidth();
final long bottomRightHeight = border.getBottomRight().getHeight();
if ( bottomLeftWidth == 0 && bottomRightWidth == 0 && bottomLeftHeight == 0 && bottomRightHeight == 0 ) {
// Make a square corner
final double lineX1 = StrictGeomUtility.toExternalValue( x );
final double lineX2 = StrictGeomUtility.toExternalValue( x + w );
final double lineY = StrictGeomUtility.toExternalValue( y + h - halfBorderWidth );
borderShapeBottom = new Line2D.Double( lineX1, lineY, lineX2, lineY );
return borderShapeBottom;
}
// Make a rounded corner
final GeneralPath generalPath = new GeneralPath( GeneralPath.WIND_NON_ZERO, 20 );
generalPath.append( configureArc( x + w - 2 * bottomRightWidth, y + h - 2 * bottomRightHeight,
2 * bottomRightWidth, 2 * bottomRightHeight, -45, -45, Arc2D.OPEN ), true );
generalPath.lineTo( (float) ( x + bottomLeftWidth ), (float) ( y + h ) ); // 6
generalPath.append( configureArc( x, y + h - 2 * bottomLeftHeight, 2 * bottomLeftWidth, 2 * bottomLeftHeight, -90,
-45, Arc2D.OPEN ), true );
generalPath.transform( BorderRenderer.scaleInstance );
borderShapeBottom = generalPath;
return generalPath;
}
private void drawPerBend(Graphics2D g, boolean sinister) {
drawBackground(g);
int colors = backgroundColors.size();
GeneralPath path = new GeneralPath();
path.moveTo(0, HEIGHT);
path.lineTo(sinister ? WIDTH : 0, 0);
path.lineTo(WIDTH, HEIGHT);
g.setColor(backgroundColors.get(1 % colors));
g.fill(path);
}
public void paintBorder(Component c, Graphics g0, int x, int y,
int width, int height) {
Graphics2D g = (Graphics2D) g0;
boolean selected = c.hasFocus();
if (c instanceof JComponent) {
JComponent jc = (JComponent) c;
Boolean pressed = (Boolean) jc
.getClientProperty("mousePressed");
if (pressed == null)
pressed = Boolean.FALSE;
if (pressed.booleanValue())
selected = true;
}
GeneralPath body = new GeneralPath(Path2D.WIND_EVEN_ODD);
body.moveTo(x, y);
body.lineTo(x + width, y);
body.lineTo(x + width, y + height);
body.lineTo(x, y + height);
body.closePath();
body.moveTo(x + 5, y + 5);
body.lineTo(x + width - 5, y + 5);
body.lineTo(x + width - 5, y + height - 5);
body.lineTo(x + 5, y + height - 5);
body.closePath();
if (!selected) {
g.setColor(fill);
} else {
Paint paint = PlafPaintUtils.getVerticalGradient(
"aquaSelectedColorWellFill", height, y, new float[] {
0, 1 }, selectedFillGradient);
g.setPaint(paint);
}
g.fill(body);
if (!selected) {
g.setColor(border);
} else {
g.setColor(borderSelected);
}
g.drawLine(x, y, x + width - 1, y);
g.drawLine(x, y + height - 1, x + width - 1, y + height - 1);
g.drawLine(x, y, x, y + height - 1);
g.drawLine(x + width - 1, y, x + width - 1, y + height - 1);
g.drawLine(x + 5, y + 5, x + width - 1 - 5, y + 5);
g.drawLine(x + 5, y + height - 1 - 5, x + width - 1 - 5, y + height
- 1 - 5);
g.drawLine(x + 5, y + 5, x + 5, y + height - 1 - 5);
g.drawLine(x + width - 1 - 5, y + 5, x + width - 1 - 5, y + height
- 1 - 5);
// side shades:
if (!selected) {
g.setPaint(PlafPaintUtils.getVerticalGradient("aquaColorWell",
height, y, new float[] { 0, 1 }, normalGradient));
} else {
g.setPaint(PlafPaintUtils.getVerticalGradient(
"aquaSelectedColorWell", height, y,
new float[] { 0, 1 }, selectedGradient));
}
g.drawLine(x + 1, y + 1, x + 1, y + height - 2);
g.drawLine(x + width - 2, y + 1, x + width - 2, y + height - 2);
}
@Override
public void paintContourBackground(Graphics g, Component comp, float width, float height,
Shape contour, boolean isFocused, SubstanceColorScheme fillScheme, boolean hasShine) {
int iWidth = (int) Math.ceil(width);
int iHeight = (int) Math.ceil(height);
// create rectangular background and later draw it on
// result image with contour clip.
BufferedImage rectangular = SubstanceCoreUtilities.getBlankImage(iWidth, iHeight);
Graphics2D rgraphics = (Graphics2D) rectangular.getGraphics();
Color lightFillColor = fillScheme.getUltraLightColor();
Color midFillColor = fillScheme.getLightColor();
Color darkFillColor = fillScheme.getMidColor();
// Fill background
GradientPaint gradientTop = new GradientPaint(0, 0, lightFillColor, width / 4, height / 2,
midFillColor);
GeneralPath clipTop = new GeneralPath();
clipTop.moveTo(0, 0);
clipTop.lineTo(width, 0);
clipTop.curveTo(5 * width / 6, height / 3, 3 * width / 4, height / 2, width / 2,
height / 2);
clipTop.curveTo(width / 3, height / 2, width / 4, height, 0, 7 * height / 8);
clipTop.lineTo(0, 0);
rgraphics.setClip(clipTop);
rgraphics.setPaint(gradientTop);
rgraphics.fillRect(0, 0, iWidth, iHeight);
GradientPaint gradientBottom = new GradientPaint(2 * width / 3, 2 * height / 3,
darkFillColor, width, height, midFillColor);
GeneralPath clipBottom = new GeneralPath();
clipBottom.moveTo(0, height);
clipBottom.lineTo(width, height);
clipBottom.lineTo(width, 0);
clipBottom.curveTo(5 * width / 6, height / 3, 3 * width / 4, height / 2, width / 2,
height / 2);
clipBottom.curveTo(width / 3, height / 2, width / 4, height, 0, 7 * height / 8);
clipBottom.lineTo(0, height);
rgraphics.setClip(clipBottom);
rgraphics.setPaint(gradientBottom);
rgraphics.fillRect(0, 0, iWidth, iHeight);
rgraphics.setClip(null);
GeneralPath mid = new GeneralPath();
mid.moveTo(width, 0);
mid.curveTo(5 * width / 6, height / 3, 3 * width / 4, height / 2, width / 2, height / 2);
mid.curveTo(width / 3, height / 2, width / 4, height, 0, 7 * height / 8);
rgraphics.draw(mid);
Graphics2D graphics = (Graphics2D) g.create();
graphics.setClip(contour);
graphics.drawImage(rectangular, 0, 0, null);
graphics.dispose();
}
private GeneralPath boundingShape(double[] path0, double[] path1) {
// Really, we want the path to be a convex hull around all of the
// points in path0 and path1. But we can get by with less than
// that. We do need to prevent the two segments which
// join path0 to path1 from crossing each other. So, if we
// traverse path0 from top to bottom, we'll traverse path1 from
// bottom to top (and vice versa).
GeneralPath result = pathToShape(path0, false, null);
boolean sameDirection;
if (isVerticalLine) {
sameDirection = (path0[1] > path0[path0.length-1]) ==
(path1[1] > path1[path1.length-1]);
}
else {
sameDirection = (path0[0] > path0[path0.length-2]) ==
(path1[0] > path1[path1.length-2]);
}
int start;
int limit;
int increment;
if (sameDirection) {
start = path1.length-2;
limit = -2;
increment = -2;
}
else {
start = 0;
limit = path1.length;
increment = 2;
}
for (int i = start; i != limit; i += increment) {
result.lineTo((float)path1[i], (float)path1[i+1]);
}
result.closePath();
return result;
}
private GeneralPath boundingShape(double[] path0, double[] path1) {
// Really, we want the path to be a convex hull around all of the
// points in path0 and path1. But we can get by with less than
// that. We do need to prevent the two segments which
// join path0 to path1 from crossing each other. So, if we
// traverse path0 from top to bottom, we'll traverse path1 from
// bottom to top (and vice versa).
GeneralPath result = pathToShape(path0, false, null);
boolean sameDirection;
if (isVerticalLine) {
sameDirection = (path0[1] > path0[path0.length-1]) ==
(path1[1] > path1[path1.length-1]);
}
else {
sameDirection = (path0[0] > path0[path0.length-2]) ==
(path1[0] > path1[path1.length-2]);
}
int start;
int limit;
int increment;
if (sameDirection) {
start = path1.length-2;
limit = -2;
increment = -2;
}
else {
start = 0;
limit = path1.length;
increment = 2;
}
for (int i = start; i != limit; i += increment) {
result.lineTo((float)path1[i], (float)path1[i+1]);
}
result.closePath();
return result;
}
private BufferedImage create_SMALL_ROSE_POINTER_Image(final int WIDTH) {
final BufferedImage IMAGE = UTIL.createImage((int) (WIDTH * 0.0546875f), (int) (WIDTH * 0.2f), java.awt.Transparency.TRANSLUCENT);
final Graphics2D G2 = IMAGE.createGraphics();
G2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
G2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
G2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
G2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
final int IMAGE_WIDTH = IMAGE.getWidth();
final int IMAGE_HEIGHT = IMAGE.getHeight();
G2.setStroke(new BasicStroke(0.75f));
// Define arrow shape of pointer
final GeneralPath POINTER_WHITE_LEFT = new GeneralPath();
final GeneralPath POINTER_WHITE_RIGHT = new GeneralPath();
POINTER_WHITE_LEFT.moveTo(IMAGE_WIDTH - IMAGE_WIDTH * 0.75f, IMAGE_HEIGHT);
POINTER_WHITE_LEFT.lineTo(IMAGE_WIDTH / 2.0f, IMAGE_HEIGHT / 2.0f);
POINTER_WHITE_LEFT.lineTo(IMAGE_WIDTH / 2.0f, IMAGE_HEIGHT);
POINTER_WHITE_LEFT.closePath();
POINTER_WHITE_RIGHT.moveTo(IMAGE_WIDTH * 0.75f, IMAGE_HEIGHT);
POINTER_WHITE_RIGHT.lineTo(IMAGE_WIDTH / 2.0f, IMAGE_HEIGHT / 2.0f);
POINTER_WHITE_RIGHT.lineTo(IMAGE_WIDTH / 2.0f, IMAGE_HEIGHT);
POINTER_WHITE_RIGHT.closePath();
final Area POINTER_FRAME_WHITE = new Area(POINTER_WHITE_LEFT);
POINTER_FRAME_WHITE.add(new Area(POINTER_WHITE_RIGHT));
final Color STROKE_COLOR = getBackgroundColor().SYMBOL_COLOR.darker();
final Color FILL_COLOR = getBackgroundColor().SYMBOL_COLOR;
G2.setColor(FILL_COLOR);
G2.fill(POINTER_FRAME_WHITE);
G2.setColor(STROKE_COLOR);
G2.draw(POINTER_FRAME_WHITE);
G2.dispose();
return IMAGE;
}
@Override
protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement, int selectedIndex,
int x, int y, int w, int h) {
TabContentPaneBorderKind kind = SubstanceCoreUtilities.getContentBorderKind(this.tabPane);
boolean isDouble = (kind == TabContentPaneBorderKind.DOUBLE_FULL)
|| (kind == TabContentPaneBorderKind.DOUBLE_PLACEMENT);
boolean isPlacement = (kind == TabContentPaneBorderKind.SINGLE_PLACEMENT)
|| (kind == TabContentPaneBorderKind.DOUBLE_PLACEMENT);
if (isPlacement) {
if (tabPlacement != SwingConstants.BOTTOM)
return;
}
Rectangle selRect = selectedIndex < 0 ? null
: this.getTabBounds(selectedIndex, this.calcRect);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_NORMALIZE);
float strokeWidth = SubstanceSizeUtils.getBorderStrokeWidth();
int joinKind = BasicStroke.JOIN_ROUND;
int capKind = BasicStroke.CAP_BUTT;
g2d.setStroke(new BasicStroke(strokeWidth, capKind, joinKind));
int offset = (int) (strokeWidth / 2.0);
int ribbonDelta = (int) Math.ceil(strokeWidth + 1.5f);
boolean isUnbroken = (tabPlacement != BOTTOM || selectedIndex < 0 || (selRect.y - 1 > h)
|| (selRect.x < x || selRect.x > x + w));
x += offset;
y += offset;
w -= 2 * offset;
h -= 2 * offset;
// Draw unbroken line if tabs are not on BOTTOM, OR
// selected tab is not in run adjacent to content, OR
// selected tab is not visible (SCROLL_TAB_LAYOUT)
SubstanceColorScheme borderScheme = SubstanceColorSchemeUtilities.getColorScheme(
this.tabPane, selectedIndex, ColorSchemeAssociationKind.TAB_BORDER,
ComponentState.SELECTED);
Color darkShadowColor = SubstanceColorUtilities.getMidBorderColor(borderScheme);
if (isUnbroken) {
g2d.setColor(this.highlight);
g2d.drawLine(x, y + h - 1, x + w, y + h - 1);
} else {
// Break line to show visual connection to selected tab
SubstanceButtonShaper shaper = SubstanceCoreUtilities.getButtonShaper(this.tabPane);
int delta = (shaper instanceof ClassicButtonShaper) ? 1 : 0;
float borderInsets = SubstanceSizeUtils.getBorderStrokeWidth() / 2.0f;
GeneralPath bottomOutline = new GeneralPath();
bottomOutline.moveTo(x, y + h - 1);
bottomOutline.lineTo(selRect.x + borderInsets, y + h - 1);
int bumpHeight = super.calculateTabHeight(tabPlacement, 0,
SubstanceSizeUtils.getComponentFontSize(this.tabPane)) / 2;
bottomOutline.lineTo(selRect.x + borderInsets, y + h + bumpHeight);
if (selRect.x + selRect.width < x + w) {
float selectionEndX = selRect.x + selRect.width - delta - 1 - borderInsets;
bottomOutline.lineTo(selectionEndX, y + h - 1 + bumpHeight);
bottomOutline.lineTo(selectionEndX, y + h - 1);
bottomOutline.lineTo(x + w, y + h - 1);
}
g2d.setPaint(new GradientPaint(x, y + h - 1, darkShadowColor, x, y + h - 1 + bumpHeight,
SubstanceColorUtilities.getAlphaColor(darkShadowColor, 0)));
g2d.draw(bottomOutline);
}
if (isDouble) {
if (tabPlacement == BOTTOM) {
g2d.setColor(this.highlight);
g2d.setColor(darkShadowColor);
g2d.drawLine(x, y + h - 1 - ribbonDelta, x + w, y + h - 1 - ribbonDelta);
}
if (tabPlacement == LEFT) {
g2d.setPaint(new GradientPaint(x, y + h - 1, darkShadowColor, x + 4 * ribbonDelta,
y + h - 1, this.highlight));
g2d.drawLine(x, y + h - 1, x + 4 * ribbonDelta, y + h - 1);
}
if (tabPlacement == RIGHT) {
g2d.setPaint(new GradientPaint(x + w - 1 - 4 * ribbonDelta, y + h - 1,
this.highlight, x + w - 1, y + h - 1, darkShadowColor));
g2d.drawLine(x + w - 1 - 4 * ribbonDelta, y + h - 1, x + w - 1, y + h - 1);
}
}
g2d.dispose();
}
private GeneralPath boundingShape(double[] path0, double[] path1) {
// Really, we want the path to be a convex hull around all of the
// points in path0 and path1. But we can get by with less than
// that. We do need to prevent the two segments which
// join path0 to path1 from crossing each other. So, if we
// traverse path0 from top to bottom, we'll traverse path1 from
// bottom to top (and vice versa).
GeneralPath result = pathToShape(path0, false, null);
boolean sameDirection;
if (isVerticalLine) {
sameDirection = (path0[1] > path0[path0.length-1]) ==
(path1[1] > path1[path1.length-1]);
}
else {
sameDirection = (path0[0] > path0[path0.length-2]) ==
(path1[0] > path1[path1.length-2]);
}
int start;
int limit;
int increment;
if (sameDirection) {
start = path1.length-2;
limit = -2;
increment = -2;
}
else {
start = 0;
limit = path1.length;
increment = 2;
}
for (int i = start; i != limit; i += increment) {
result.lineTo((float)path1[i], (float)path1[i+1]);
}
result.closePath();
return result;
}