【问题标题】:How to create rounded corner BevelBorder in Java Swing?如何在 Java Swing 中创建圆角 BevelBorder?
【发布时间】:2012-07-04 01:33:20
【问题描述】:

我想使用斜角边框,因为它有点 3D,但我不知道如何创建圆角斜角边框。

SoftBevelBorder 不起作用,因为圆角半径太小。如何让边角更圆?

【问题讨论】:

标签: java swing border


【解决方案1】:

这里有一个圆角边框的例子,你可以在其中调整半径:

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

不是斜面,但是你可以在SoftBevelBorder的源代码中看到如何实现“斜面”。 如果你能做到,我会对代码感兴趣:)

【讨论】:

  • 我知道几年后,但如果您仍然感兴趣,请查看我的回答
【解决方案2】:

为了获得正确的边框形状,您需要覆盖AbstractBorder.paintBorder(...) 方法。当你这样做时,你可以在方法中添加与此类似的代码。

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

现在有两种主要方法可以在边框周围绘制斜角效果,但取决于您希望斜角的复杂程度,取决于您使用哪种方式。对于使用 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));

但是,如果您想使用更复杂的斜角边框,它使用 4 种不同的颜色,则需要查看 javax.swing.border.BevelBorder 的源代码。这将表明您需要一段类似的代码。

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

如果颜色在拐角一半处停止很重要,您也可以使用以下代码。

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

当我们把所有这些放在一起时,你会得到一个看起来像这样的类。

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));
        }
    }
}

现在您可以通过 yourComponent.setBorder(new RoundedBorder(10)); 或使用 RoundedBorder 类的其他构造函数之一在您的组件上实现此类。

【讨论】:

  • 我试过了,它看起来确实是圆的,但没有斜角,至少不像BevelBorder那样...
  • @lbalazscs 感谢您的反馈。我应该在发布之前尝试使用初始斜角边框颜色。我已经编辑了代码,这样当您使用yourComponent.setBorder(new RoundedBorder(10)); 时,默认情况下它看起来会更“斜边”(很确定这不是一个词:P)
  • @lbalazscs 你会说它看起来更好还是我应该以某种方式改变它?
  • 现在好多了,更“斜边”了:) 这应该是公认的答案,不是我的。
  • @lbalazscs 我很高兴它是你的,因为我从你的回答中得到了这个想法。我刚刚实现了它:) 再次感谢您的反馈
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多