简体   繁体   English

如何在Java Swing中创建圆角BevelBorder?

[英]How to create rounded corner BevelBorder in Java Swing?

I want to use a Bevel Border because it is sort of 3D but I don't know how to create a rounded corner BevelBorder. 我想使用斜面边框,因为它有点3D但我不知道如何创建圆角BevelBorder。

SoftBevelBorder does not work because the rounded radius is too small. SoftBevelBorder不起作用,因为圆角半径太小。 How to make the corners more round? 如何使角落更圆?

Here there is an example of rounded border, where you can adjust the radius: 这里有一个圆角边框示例,您可以在其中调整半径:

http://java-swing-tips.blogspot.co.at/2012/03/rounded-border-for-jtextfield.html http://java-swing-tips.blogspot.co.at/2012/03/rounded-border-for-jtextfield.html

Not bevel, but you can see how to achieve the "bevelness" in the source code of SoftBevelBorder. 不是斜角,但你可以看到如何在SoftBevelBorder的源代码中实现“斜面”。 If you manage to do it, I would be interested in the code :) 如果你设法做到这一点,我会对代码感兴趣:)

In order to get the correct border shape you need to override the AbstractBorder.paintBorder(...) method. 为了获得正确的边框形状,您需要覆盖AbstractBorder.paintBorder(...)方法。 When you do that you can add code similar to this to the method. 执行此操作时,可以向该方法添加与此类似的代码。

super.paintBorder(c, g, x, y, width, height);

Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));

Shape clip = g2d.getClip();
Area rect = new Area(clip);
rect.subtract(new Area(new RoundRectangle2D.Double(x, y, width, height, radii, radii)));
g2d.setClip(rect);
g2d.setColor(c.getParent().getBackground());
g2d.fillRect(0, 0, width, height);
g2d.setClip(clip);
g2d.draw(rect);

Now there are two main ways you can draw a bevel effect around the border but depending on the complexity you want the bevel to be, depends on which way you use. 现在有两种主要方法可以在边框周围绘制斜角效果,但取决于您想要斜角的复杂程度,取决于您使用的方式。 For a simple bevel border that uses 2 colours, you can use something similar to this. 对于使用2种颜色的简单斜角边框,您可以使用与此类似的东西。

g2d.setColor(inner); //Inner Rectangle
g2d.draw(new RoundRectangle2D.Double(x + 1, y + 1, width - 2, height - 2, radii, radii));

g2d.setColor(outer); //Outer Rectangle
g2d.draw(new RoundRectangle2D.Double(x, y, width - 2, height - 2, radii, radii));

However, if you want to use a more complex bevel border that uses 4 different colours, you will need to look at the source code of javax.swing.border.BevelBorder . 但是,如果要使用使用4种不同颜色的更复杂的斜角边框,则需要查看javax.swing.border.BevelBorder的源代码。 This will show you that you need a piece of code similar to this. 这将向您显示您需要一段与此类似的代码。

double offset = radii / 2;
//Outer
g2d.setColor(outerH);
g2d.draw(new Line2D.Double(0, offset, 0, height - 2 - offset)); //Left
g2d.draw(new Line2D.Double(1 + offset, 0, width - 2 - offset, 0)); //Top
g2d.draw(new Arc2D.Double(width - radii - 1, 0, radii, radii, 0, 90, Arc2D.OPEN)); //Top Right
g2d.draw(new Arc2D.Double(0, 0, radii, radii, 90, 90, Arc2D.OPEN)); //Top Left

//Inner
g2d.setColor(innerH);
g2d.draw(new Line2D.Double(1, 1 + offset, 1, height - 3 - offset)); //Left
g2d.draw(new Line2D.Double(2 + offset, 1, width - 3 - offset, 1)); //Top
g2d.draw(new Arc2D.Double(width - radii - 2, 1, radii, radii, 0, 90, Arc2D.OPEN)); //Top Right
g2d.draw(new Arc2D.Double(1, 1, radii, radii, 90, 90, Arc2D.OPEN)); //Top Left

//Outer
g2d.setColor(outer);
g2d.draw(new Line2D.Double(offset, height - 1, width - 1 - offset, height - 1)); //Bottom
g2d.draw(new Line2D.Double(width - 1, offset, width - 1, height - 2 - offset)); //Right
g2d.draw(new Arc2D.Double(width - radii - 1, height - radii - 1, radii, radii, 270, 90, Arc2D.OPEN)); //Bottom Right
g2d.draw(new Arc2D.Double(0, height - radii - 1, radii, radii, 180, 90, Arc2D.OPEN)); //Bottom Left

//Inner
g2d.setColor(inner);
g2d.draw(new Line2D.Double(1 + offset, height - 2, width - 2 - offset, height - 2)); //Bottom
g2d.draw(new Line2D.Double(width - 2, 1 + offset, width - 2, height - 3 - offset)); //Right
g2d.draw(new Arc2D.Double(width - radii - 2, height - radii - 2, radii, radii, 270, 90, Arc2D.OPEN)); //Bottom Right
g2d.draw(new Arc2D.Double(1, height - radii - 2, radii, radii, 180, 90, Arc2D.OPEN)); //Bottom Left

You may also use the following code if it is important for the color to stop half way around the corner. 如果颜色在拐角处中途停止很重要,您也可以使用以下代码。

double offset = radii / 2;
//Outer
g2d.setColor(outerH);
g2d.draw(new Line2D.Double(0, offset, 0, height - 2 - offset)); //Left
g2d.draw(new Line2D.Double(1 + offset, 0, width - 2 - offset, 0)); //Top
g2d.draw(new Arc2D.Double(width - radii - 1, 0, radii, radii, 45, 45, Arc2D.OPEN)); //Top Right P1
g2d.draw(new Arc2D.Double(0, 0, radii, radii, 90, 90, Arc2D.OPEN)); //Top Left
g2d.draw(new Arc2D.Double(0, height - radii - 1, radii, radii, 180, 45, Arc2D.OPEN)); //Bottom Left P1

//Inner
g2d.setColor(innerH);
g2d.draw(new Line2D.Double(1, 1 + offset, 1, height - 3 - offset)); //Left
g2d.draw(new Line2D.Double(2 + offset, 1, width - 3 - offset, 1)); //Top
g2d.draw(new Arc2D.Double(width - radii - 2, 1, radii, radii, 45, 45, Arc2D.OPEN)); //Top Right P1
g2d.draw(new Arc2D.Double(1, 1, radii, radii, 90, 90, Arc2D.OPEN)); //Top Left
g2d.draw(new Arc2D.Double(1, height - radii - 2, radii, radii, 180, 45, Arc2D.OPEN)); //Bottom Left P1

//Outer
g2d.setColor(outerS);
g2d.draw(new Line2D.Double(offset, height - 1, width - 1 - offset, height - 1)); //Bottom
g2d.draw(new Line2D.Double(width - 1, offset, width - 1, height - 2 - offset)); //Right
g2d.draw(new Arc2D.Double(width - radii - 1, 0, radii, radii, 0, 45, Arc2D.OPEN)); //Top Right P2
g2d.draw(new Arc2D.Double(width - radii - 1, height - radii - 1, radii, radii, 270, 90, Arc2D.OPEN)); //Bottom Right
g2d.draw(new Arc2D.Double(0, height - radii - 1, radii, radii, 225, 45, Arc2D.OPEN)); //Bottom Left P2

//Inner
g2d.setColor(innerS);
g2d.draw(new Line2D.Double(1 + offset, height - 2, width - 2 - offset, height - 2)); //Bottom
g2d.draw(new Line2D.Double(width - 2, 1 + offset, width - 2, height - 3 - offset)); //Right
g2d.draw(new Arc2D.Double(width - radii - 2, 1, radii, radii, 0, 45, Arc2D.OPEN)); //Top Right P2
g2d.draw(new Arc2D.Double(width - radii - 2, height - radii - 2, radii, radii, 270, 90, Arc2D.OPEN)); //Bottom Right
g2d.draw(new Arc2D.Double(1, height - radii - 2, radii, radii, 225, 45, Arc2D.OPEN)); //Bottom Left P2

When we put all this together you get a class that looks like this. 当我们将所有这些放在一起时,你得到一个看起来像这样的课程。

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Arc2D;
import java.awt.geom.Area;
import java.awt.geom.Line2D;
import java.awt.geom.RoundRectangle2D;

import javax.swing.border.AbstractBorder;

@SuppressWarnings("serial")
public class RoundedBorder extends AbstractBorder {
    private int radii;
    private Insets insets;
    private Color innerS = new Color(166, 166, 166);
    private Color outerS = new Color(116, 116, 116);
    private Color innerH = Color.WHITE; 
    private Color outerH = Color.WHITE;
    private boolean tColor = false;

    public RoundedBorder(int radius) {
        radii = radius;
    }

    public RoundedBorder(int radius, Insets i) {
        radii = radius;
        insets = i;
    }

    public RoundedBorder(int radius, Insets i, Color out, Color in) {
        radii = radius;
        insets = i;
        innerS = in;
        outerS = out;
        tColor = true;
    }

    public RoundedBorder(int radius, Insets i, Color outH, Color inH, Color outS, Color inS) {
        radii = radius;
        insets = i;
        innerS = inS;
        outerS = outS;
        innerH = inH;
        outerH = outH;
    }

    @Override
    public Insets getBorderInsets(Component c) {
        if(insets != null) {
            return insets;
        }
        return new Insets(5, 5, 5, 5);
    }

    @Override
    public Insets getBorderInsets(Component c, Insets insets) {
        return getBorderInsets(c);
    }

    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        super.paintBorder(c, g, x, y, width, height);

        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));

        Shape clip = g2d.getClip();
        Area rect = new Area(clip);
        rect.subtract(new Area(new RoundRectangle2D.Double(x, y, width, height, radii, radii)));
        g2d.setClip(rect);
        g2d.setColor(c.getParent().getBackground());
        g2d.fillRect(0, 0, width, height);
        g2d.setClip(clip);
        g2d.draw(rect);

        if(!tColor) {
            double offset = radii / 2;
            //Outer
            g2d.setColor(outerH);
            g2d.draw(new Line2D.Double(0, offset, 0, height - 2 - offset)); //Left
            g2d.draw(new Line2D.Double(1 + offset, 0, width - 2 - offset, 0)); //Top
            g2d.draw(new Arc2D.Double(width - radii - 1, 0, radii, radii, 45, 45, Arc2D.OPEN)); //Top Right P1
            g2d.draw(new Arc2D.Double(0, 0, radii, radii, 90, 90, Arc2D.OPEN)); //Top Left
            g2d.draw(new Arc2D.Double(0, height - radii - 1, radii, radii, 180, 45, Arc2D.OPEN)); //Bottom Left P1

            //Inner
            g2d.setColor(innerH);
            g2d.draw(new Line2D.Double(1, 1 + offset, 1, height - 3 - offset)); //Left
            g2d.draw(new Line2D.Double(2 + offset, 1, width - 3 - offset, 1)); //Top
            g2d.draw(new Arc2D.Double(width - radii - 2, 1, radii, radii, 45, 45, Arc2D.OPEN)); //Top Right P1
            g2d.draw(new Arc2D.Double(1, 1, radii, radii, 90, 90, Arc2D.OPEN)); //Top Left
            g2d.draw(new Arc2D.Double(1, height - radii - 2, radii, radii, 180, 45, Arc2D.OPEN)); //Bottom Left P1

            //Outer
            g2d.setColor(outerS);
            g2d.draw(new Line2D.Double(offset, height - 1, width - 1 - offset, height - 1)); //Bottom
            g2d.draw(new Line2D.Double(width - 1, offset, width - 1, height - 2 - offset)); //Right
            g2d.draw(new Arc2D.Double(width - radii - 1, 0, radii, radii, 0, 45, Arc2D.OPEN)); //Top Right P2
            g2d.draw(new Arc2D.Double(width - radii - 1, height - radii - 1, radii, radii, 270, 90, Arc2D.OPEN)); //Bottom Right
            g2d.draw(new Arc2D.Double(0, height - radii - 1, radii, radii, 225, 45, Arc2D.OPEN)); //Bottom Left P2

            //Inner
            g2d.setColor(innerS);
            g2d.draw(new Line2D.Double(1 + offset, height - 2, width - 2 - offset, height - 2)); //Bottom
            g2d.draw(new Line2D.Double(width - 2, 1 + offset, width - 2, height - 3 - offset)); //Right
            g2d.draw(new Arc2D.Double(width - radii - 2, 1, radii, radii, 0, 45, Arc2D.OPEN)); //Top Right P2
            g2d.draw(new Arc2D.Double(width - radii - 2, height - radii - 2, radii, radii, 270, 90, Arc2D.OPEN)); //Bottom Right
            g2d.draw(new Arc2D.Double(1, height - radii - 2, radii, radii, 225, 45, Arc2D.OPEN)); //Bottom Left P2
        } else {
            g2d.setColor(innerS); //Inner Rectangle
            g2d.draw(new RoundRectangle2D.Double(x + 1, y + 1, width - 2, height - 2, radii, radii));

            g2d.setColor(outerS); //Outer Rectangle
            g2d.draw(new RoundRectangle2D.Double(x, y, width - 2, height - 2, radii, radii));
        }
    }
}

Now you can implement this class on your component by just doing yourComponent.setBorder(new RoundedBorder(10)); 现在,您只需执行yourComponent.setBorder(new RoundedBorder(10));就可以在组件上实现此类yourComponent.setBorder(new RoundedBorder(10)); or by using one of the other constructors for the RoundedBorder class. 或者使用RoundedBorder类的其他构造函数之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM