如何使用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
相关产品推荐
相关产品推荐

