Reputation: 16067
I need to create a rounded border on one side of a component only.
This code creates a rounded border:
new LineBorder(Color.RED, 3, true)
I have seen this thread which shows you how to create a matte border that can be used on one side of a component only, however a matte border isn't rounded.
Is it possible to have a rounded border on one side only?
Edit:
I have tried using compound border like this:
cell.setBorder(BorderFactory.createCompoundBorder(
new LineBorder(borderColor, 3, true),
BorderFactory.createMatteBorder(0, 3, 0, 0, Color.black)));
But it doesn't work...
Upvotes: 9
Views: 5612
Reputation: 2019
public static final int TOP_LEFT = 1;
public static final int TOP_RIGHT = 2;
public static final int BOTTOM_LEFT = 4;
public static final int BOTTOM_RIGHT = 8;
public static final int ALL_CORNERS = TOP_LEFT + TOP_RIGHT + BOTTOM_LEFT + BOTTOM_RIGHT;
public static void drawRoundRect(Graphics g, Color fillColor, Color borderColor, int x, int y, int width, int height, int radius, int cornerMask)
{
// // XXX Old code (without selectively disabled round corners):
// if (fillColor != null)
// {
// og.setColor(fillColor);
// og.fillRoundRect(x, y, width - 1, height - 1, radius, radius);
// }
// if (borderColor != null && !borderColor.equals(fillColor))
// {
// og.setColor(borderColor);
// og.drawRoundRect(x, y, width - 1, height - 1, radius, radius);
// }
radius += radius % 2; // so we don't have to deal with rounding issues for odd numbers
int radiusHalf = radius / 2;
width--;
height--;
if (fillColor != null)
{
g.setColor(fillColor);
// og.fillRoundRect(x, y, width - 1, height - 1, radius, radius);
if ((cornerMask & TOP_LEFT) > 0)
{
g.fillArc(x, y, radius, radius, 90, 90);
}
else
{
g.fillRect(x, y, radiusHalf, radiusHalf);
}
if ((cornerMask & TOP_RIGHT) > 0)
{
g.fillArc(x + width - radius, y, radius, radius, 0, 90);
}
else
{
g.fillRect(x + width - radiusHalf, y, radiusHalf, radiusHalf);
}
if ((cornerMask & BOTTOM_RIGHT) > 0)
{
g.fillArc(x + width - radius, y + height - radius, radius, radius, 270, 90);
}
else
{
g.fillRect(x + width - radiusHalf, y + height - radiusHalf, radiusHalf, radiusHalf);
}
if ((cornerMask & BOTTOM_LEFT) > 0)
{
g.fillArc(x, y + height - radius, radius, radius, 180, 90);
}
else
{
g.fillRect(x, y + height - radiusHalf, radiusHalf, radiusHalf);
}
g.fillRect(x + radiusHalf, y, width - radius, radiusHalf);
g.fillRect(x + radiusHalf, y + height - radiusHalf, width - radius, radiusHalf);
g.fillRect(x, y + radiusHalf, radiusHalf, height - radius);
g.fillRect(x + width - radiusHalf, y + radiusHalf, radiusHalf, height - radius);
g.fillRect(x + radiusHalf, y + radiusHalf, width - radius, height - radius);
}
if (borderColor != null && !borderColor.equals(fillColor))
{
g.setColor(borderColor);
// XXX: there are problems with this when using semi-transparent colors + borderSize > 1
// XXX: this could be changed to to use ONE draw action using drawShape with GeneralPath.curveTo()
// XXX: this then could also be used to FILL the shape (see above)
if ((cornerMask & TOP_LEFT) > 0)
{
g.drawArc(x, y, radius, radius, 90, 90);
}
else
{
g.drawLine(x, y, x + radiusHalf, y);
g.drawLine(x, y, x, y + radiusHalf);
}
if ((cornerMask & TOP_RIGHT) > 0)
{
g.drawArc(x + width - radius, y, radius, radius, 0, 90);
}
else
{
g.drawLine(x + width - radiusHalf, y, x + width, y);
g.drawLine(x + width, y, x + width, y + radiusHalf);
}
if ((cornerMask & BOTTOM_RIGHT) > 0)
{
g.drawArc(x + width - radius, y + height - radius, radius, radius, 270, 90);
}
else
{
g.drawLine(x + width - radiusHalf, y + height, x + width, y + height);
g.drawLine(x + width, y + height - radiusHalf, x + width, y + height);
}
if ((cornerMask & BOTTOM_LEFT) > 0)
{
g.drawArc(x, y + height - radius, radius, radius, 180, 90);
}
else
{
g.drawLine(x, y + height, x + radiusHalf, y + height);
g.drawLine(x, y + height - radiusHalf, x, y + height);
}
g.drawLine(x + radiusHalf, y, x + width - radiusHalf, y); // top
g.drawLine(x + width, y + radiusHalf, x + width, y + height - radiusHalf); // right
g.drawLine(x + radiusHalf, y + height, x + width - radiusHalf, y + height); // bottom
g.drawLine(x, y + radiusHalf, x, y + height - radiusHalf); // left
}
}
Upvotes: 1
Reputation: 562
Here is one example,
JPanel content = new JPanel();
content.setBorder(BorderFactory.createEmptyBorder(1,30,1,1));
Upvotes: 0
Reputation: 3895
Here is an example on how to use Graphics2D#clipRect()
.
This code just keep the two right rounded corners and has normal borders on the left. As mentioned above, you will have to use this code inside your custom LineBorder
.
Graphics2D g2d = (Graphics2D) g;
g2d.clipRect(150, 10, 100, 100);
g2d.draw(new RoundRectangle2D.Double(100, 10, 80, 30, 15, 15));
g2d.setClip(null);
g2d.clipRect(100, 10, 50, 100);
g2d.draw(new Rectangle2D.Double(100, 10, 80, 30));
Upvotes: 3
Reputation: 57421
You can override the method of LineBorder and draw all you need there From sources of LineBorder
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Color oldColor = g.getColor();
int i;
/// PENDING(klobad) How/should do we support Roundtangles?
g.setColor(lineColor);
for(i = 0; i < thickness; i++) {
if(!roundedCorners)
g.drawRect(x+i, y+i, width-i-i-1, height-i-i-1);
else
SET CLIP HERE TO DRAW ONLY NECESSARY PART
g.drawRoundRect(x+i, y+i, width-i-i-1, height-i-i-1, thickness, thickness);
}
g.setColor(oldColor);
}
Upvotes: 6
Reputation: 88757
LineBorder
only supports all corners rounded or not. A compound border (as the JavaDoc states) uses one border for the outside and one for the inside and thus does not distinguish between left/right or top/bottom.
I'm afraid you'd either have to write your own Border
implementation or look for one that's already made by someone else (external library).
Upvotes: 3