/**
* Copyright (C) 2015 Valkyrie RCP
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.valkyriercp.component;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
/**
* A rounded border implementation copied from <code>com.publicobject.misc.swing</code>.
*
* @author <a href = "mailto:julio.arguello@gmail.com" >Julio Arg??ello (JAF)</a>
*/
public class RoundedBorder extends AbstractBorder {
/**
* This is a <code>Serializable</code> class.
*/
private static final long serialVersionUID = 728818763812538126L;
/**
* The insets.
*/
private Insets insets;
/**
* The stroke.
*/
private Stroke stroke;
/**
* The stroke color.
*/
private Color strokeColor;
/**
* The arc.
*/
private int arc;
/**
* The stroke width.
*/
private float strokeWidth;
/**
* Simple rounded border with no outline.
*
* @param arc
* the arc.
*/
public RoundedBorder(int arc) {
this.arc = arc;
final int i = (int) (arc / Math.PI) / 2;
this.insets = new Insets(i, i, i, i);
}
/**
* Rounded border with an outline.
*
* @param arc
* the arc.
* @param strokeWidth
* width of the outline.
* @param color
* color of the outline.
*/
public RoundedBorder(int arc, float strokeWidth, Color color) {
this.arc = arc;
int i = (int) ((arc / Math.PI) + ((strokeWidth * 2) / (Math.PI)));
this.insets = new Insets(i, i, i, i);
this.stroke = new BasicStroke(strokeWidth);
this.strokeColor = color;
this.strokeWidth = strokeWidth;
}
/**
* {@inheritDoc}
*/
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
final Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// In real code optimize by preserving the rect between calls
if (stroke != null) {
final int i = (int) strokeWidth / 2;
final RoundRectangle2D.Float rect = //
new RoundRectangle2D.Float(i, i, width - strokeWidth, height - strokeWidth, arc, arc);
g2.translate(x, y);
g2.setColor(c.getBackground());
g2.fill(rect);
g2.setColor(strokeColor);
g2.setStroke(stroke);
g2.draw(rect);
} else {
final RoundRectangle2D.Float rect = new RoundRectangle2D.Float(0, 0, width, height, arc, arc);
g2.translate(x, y);
g2.setColor(c.getBackground());
g2.fill(rect);
}
}
/*
* boring stuff from here on...
*/
/**
* {@inheritDoc}
*/
public Insets getBorderInsets(Component c) {
return this.insets;
}
/**
* {@inheritDoc}
*/
public Insets getBorderInsets(Component c, Insets insets) {
return this.insets;
}
/**
* {@inheritDoc}
*/
public Rectangle getInteriorRectangle(Component c, int x, int y, int width, int height) {
return RoundedBorder.getInteriorRectangle(c, this, x, y, width, height);
}
/**
* Gets the interior rectangle.
*
* @param c
* the target component.
* @param b
* the border.
* @param x
* the x coordinate.
* @param y
* the y coordinate.
* @param width
* the width.
* @param height
* the height.
* @return the rectangle.
*/
public static Rectangle getInteriorRectangle(Component c, Border b, int x, int y, int width, int height) {
final Insets insets;
if (b != null) {
insets = b.getBorderInsets(c);
} else {
insets = new Insets(0, 0, 0, 0);
}
return new Rectangle(x + insets.left, //
y + insets.top, //
width - insets.right - insets.left, //
height - insets.top - insets.bottom);
}
}