9

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...

Community
  • 1
  • 1
David
  • 15,652
  • 26
  • 115
  • 156

5 Answers5

6

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);
    }
StanislavL
  • 56,971
  • 9
  • 68
  • 98
  • Relacing `g.drawRoundRect(...)` doesn't seem trivial, IMO. But it's a start - you'd have to draw the round corners and the edges separately. – Thomas Aug 12 '11 at 13:48
  • @Thomas Easier said than done :P It's beyond me to draw the rounded corners with arcs. I've been trying but didn't manage yet. – David Aug 12 '11 at 14:28
  • As I said, it's not trivial, meaning "not that easy" :) – Thomas Aug 12 '11 at 14:31
  • @Thomas http://www.docjar.com/html/api/java/awt/Graphics.java.html I can't understand. Why is there the source code of EVERYTHING except drawRoundRect and fillRoundRect????! – David Aug 12 '11 at 14:50
  • @David `Graphics` is an abstract class, you need to find the concrete subclass that implements those methods. Try [SunGraphics2D](http://www.docjar.com/html/api/sun/java2d/SunGraphics2D.java.html). – Thomas Aug 12 '11 at 14:58
  • 1
    @David for example http://stackoverflow.com/questions/5751311/creating-custom-button-in-java/5755124#5755124, +1 – mKorbel Aug 12 '11 at 16:41
  • @mKorbel Yes but that uses `.drawRoundRect` not `.drawArc` :( I can't use drawRoundRect because I need only one side of the border (not all four). – David Aug 12 '11 at 18:21
  • 1
    @David nothing against your person, but as in your last post I think that you don't see the forest for the trees :-), java.awt.Border has four sides by default, I saw around some threads with topic about how to extract/change/colored particular Border from possitions (NORTH/SOUTH/WEST/EAST) http://www.java2s.com/Tutorial/Java/0240__Swing/1530__AbstractBorder.htm and another... – mKorbel Aug 12 '11 at 18:45
3

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).

Thomas
  • 87,414
  • 12
  • 119
  • 157
3

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));
aymeric
  • 3,877
  • 2
  • 28
  • 42
1
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
    }
}
Frederic Leitenberger
  • 1,949
  • 24
  • 32
0

Here is one example,

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

Annu
  • 532
  • 4
  • 8
  • 22