David
David

Reputation: 16067

Rounded Border on one side only java

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

Answers (5)

Frederic Leitenberger
Frederic Leitenberger

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

Annu
Annu

Reputation: 562

Here is one example,

JPanel content = new JPanel(); content.setBorder(BorderFactory.createEmptyBorder(1,30,1,1));

Upvotes: 0

aymeric
aymeric

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

StanislavL
StanislavL

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

Thomas
Thomas

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

Related Questions