You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Java为指定Swing组件设置自定义圆角边框

如何使用Java为指定Swing组件设置自定义圆角边框

嘿,我来帮你搞定这个Swing组件的圆角边框问题!根据你的需求,我们需要给不同组件设置针对性的圆角样式——毕竟Swing默认的边框组件没法直接实现“只让某两个角圆角”的效果,所以咱们得自定义一个Border类来实现这个功能。下面我会结合你给出的代码,一步步修改达到你想要的效果。

首先,我们需要创建一个继承自AbstractBorder的自定义边框类,重写paintBorder方法,利用Graphics2D的圆角矩形绘制能力,精准控制哪些角需要圆角、哪些角保持直角:

import javax.swing.border.AbstractBorder;
import java.awt.*;

class CustomRoundBorder extends AbstractBorder {
    private final int radius;
    private final boolean topLeft, topRight, bottomLeft, bottomRight;

    // 构造方法:指定圆角半径,以及四个角是否需要圆角
    public CustomRoundBorder(int radius, boolean topLeft, boolean topRight, boolean bottomLeft, boolean bottomRight) {
        this.radius = radius;
        this.topLeft = topLeft;
        this.topRight = topRight;
        this.bottomLeft = bottomLeft;
        this.bottomRight = bottomRight;
    }

    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        Graphics2D g2d = (Graphics2D) g.create();
        // 开启抗锯齿,让圆角更平滑
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(c.getBackground());

        // 先绘制完整的圆角矩形
        g2d.fillRoundRect(x, y, width - 1, height - 1, radius, radius);
        // 不需要圆角的角,用直角矩形覆盖掉对应的圆角部分
        if (!topLeft) {
            g2d.fillRect(x, y, radius, radius);
        }
        if (!topRight) {
            g2d.fillRect(x + width - radius, y, radius, radius);
        }
        if (!bottomLeft) {
            g2d.fillRect(x, y + height - radius, radius, radius);
        }
        if (!bottomRight) {
            g2d.fillRect(x + width - radius, y + height - radius, radius, radius);
        }

        g2d.dispose();
    }

    // 调整组件内边距,避免内容被圆角裁剪
    @Override
    public Insets getBorderInsets(Component c) {
        return new Insets(radius/2, radius/2, radius/2, radius/2);
    }

    @Override
    public Insets getBorderInsets(Component c, Insets insets) {
        insets.left = insets.top = insets.right = insets.bottom = radius/2;
        return insets;
    }
}

接下来,我们把这个自定义边框应用到你的各个组件上,替换原来的setBorder(null)设置:

1. 给user_icon和lock_icon设置左上/左下圆角(4px)

这两个组件需要左上、左下是4px圆角,右上、右下保持直角,直接替换边框设置即可:

user_icon.setBorder(new CustomRoundBorder(4, true, false, true, false));
lock_icon.setBorder(new CustomRoundBorder(4, true, false, true, false));

2. 给username和password设置右上/右下圆角(4px)

这两个输入框需要右上、右下是4px圆角,同时你原来加了左侧内边距,所以我们把自定义圆角边框和空边框组合成复合边框:

username.setBorder(BorderFactory.createCompoundBorder(
        new CustomRoundBorder(4, false, true, false, true),
        BorderFactory.createEmptyBorder(0, 10, 0, 0)
));

password.setBorder(BorderFactory.createCompoundBorder(
        new CustomRoundBorder(4, false, true, false, true),
        BorderFactory.createEmptyBorder(0, 10, 0, 0)
));

3. 给login按钮设置四个角都为4px圆角

按钮需要四个角都是4px圆角,直接替换边框设置:

login.setBorder(new CustomRoundBorder(4, true, true, true, true));

最后是修改后的完整代码片段,你可以直接替换原有代码使用:

// 先定义自定义边框类(可以放在你的主类内部作为内部类,或者单独成一个类)
class CustomRoundBorder extends AbstractBorder {
    private final int radius;
    private final boolean topLeft, topRight, bottomLeft, bottomRight;

    public CustomRoundBorder(int radius, boolean topLeft, boolean topRight, boolean bottomLeft, boolean bottomRight) {
        this.radius = radius;
        this.topLeft = topLeft;
        this.topRight = topRight;
        this.bottomLeft = bottomLeft;
        this.bottomRight = bottomRight;
    }

    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(c.getBackground());

        g2d.fillRoundRect(x, y, width - 1, height - 1, radius, radius);
        if (!topLeft) g2d.fillRect(x, y, radius, radius);
        if (!topRight) g2d.fillRect(x + width - radius, y, radius, radius);
        if (!bottomLeft) g2d.fillRect(x, y + height - radius, radius, radius);
        if (!bottomRight) g2d.fillRect(x + width - radius, y + height - radius, radius, radius);

        g2d.dispose();
    }

    @Override
    public Insets getBorderInsets(Component c) {
        return new Insets(radius/2, radius/2, radius/2, radius/2);
    }

    @Override
    public Insets getBorderInsets(Component c, Insets insets) {
        insets.left = insets.top = insets.right = insets.bottom = radius/2;
        return insets;
    }
}

// 你的原有代码修改后:
user_icon = new JPanel();
user_icon.setBackground(new Color(238, 238, 238));
user_icon.setBorder(new CustomRoundBorder(4, true, false, true, false));
user_icon.setBounds(212, 120, 40, 44);
container.add(user_icon);
user_icon.setLayout(null);

username = new JTextField();
username.setFocusable(false);
username.setBackground(new Color(245, 245, 245));
username.setText("Username");
username.setForeground(Color.GRAY);
username.setBorder(BorderFactory.createCompoundBorder(
        new CustomRoundBorder(4, false, true, false, true),
        BorderFactory.createEmptyBorder(0, 10, 0, 0)
));
username.setBounds(252, 120, 220, 44);
container.add(username);
username.setColumns(10);

lock_icon = new JPanel();
lock_icon.setBackground(new Color(238, 238, 238));
lock_icon.setBorder(new CustomRoundBorder(4, true, false, true, false));
lock_icon.setBounds(212, 175, 40, 44);
container.add(lock_icon);
lock_icon.setLayout(null);

password = new JPasswordField();
password.setFont(new Font("Tahoma", Font.PLAIN, 11));
password.setFocusable(false);
password.setEchoChar((char) 0);
password.setBackground(new Color(245, 245, 245));
password.setText("Password");
password.setForeground(Color.GRAY);
password.setBorder(BorderFactory.createCompoundBorder(
        new CustomRoundBorder(4, false, true, false, true),
        BorderFactory.createEmptyBorder(0, 10, 0, 0)
));
password.setBounds(252, 175, 220, 44);
container.add(password);

JButton login = new JButton("SIGN IN");
login.setForeground(Color.WHITE);
login.setBackground(new Color(229, 33, 35));
login.setFont(new Font("SansSerif", Font.BOLD, 12));
login.setBorder(new CustomRoundBorder(4, true, true, true, true));
login.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
login.setFocusPainted(false);
login.setContentAreaFilled(false);
login.setOpaque(true);
login.setBounds(212, 268, 260, 44);
container.add(login);

备注:内容来源于stack exchange,提问作者user22399010

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 15:14:28