如何实现半圆角边框?修改RoundPanel仅保留左侧圆角
修改RoundPanel实现仅左侧圆角
要实现仅左侧两个角落为圆角、右侧直角的效果,需要自定义绘制路径——默认的fillRoundRect和drawRoundRect无法单独指定某几个角的圆角。以下是修改后的完整代码:
修改后的RoundPanel类
import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.geom.GeneralPath; import javax.swing.JPanel; public class RoundPanel extends JPanel { private static final long serialVersionUID = 1L; private Shape shape; private final int cornerRadius; public RoundPanel(int cornerRadius) { this.cornerRadius = cornerRadius; setOpaque(false); } @Override protected void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D) g.create(); g2d.setColor(getBackground()); shape = createLeftRoundedShape(); g2d.fill(shape); super.paintComponent(g); g2d.dispose(); } @Override protected void paintBorder(Graphics g) { Graphics2D g2d = (Graphics2D) g.create(); g2d.setColor(getForeground()); g2d.draw(createLeftRoundedShape()); g2d.dispose(); } @Override public boolean contains(int x, int y) { if (shape == null || !shape.getBounds().equals(getBounds())) { shape = createLeftRoundedShape(); } return shape.contains(x, y); } // 构建仅左侧带圆角的形状 private Shape createLeftRoundedShape() { int width = getWidth(); int height = getHeight(); int radius = Math.min(cornerRadius, height / 2); // 避免圆角半径超过组件高度的一半 GeneralPath path = new GeneralPath(); // 绘制路径:左上圆角右侧 → 右上角 → 右下角 → 左下圆角右侧 → 左下圆角弧 → 左上圆角下方 → 左上圆角弧 → 闭合 path.moveTo(radius, 0); path.lineTo(width, 0); path.lineTo(width, height); path.lineTo(radius, height); path.arcTo(0, height - 2 * radius, 2 * radius, 2 * radius, 0, -90); path.lineTo(0, radius); path.arcTo(0, 0, 2 * radius, 2 * radius, 270, 90); path.closePath(); return path; } }
关键改动说明
- 复用圆角参数:新增
cornerRadius成员变量,修复原代码中构造参数未使用的问题,支持自定义圆角大小。 - 自定义路径绘制:通过
GeneralPath手动构建形状,仅在左上、左下两个角落绘制圆角弧,右侧保持直角。 - 完善交互判断:
contains方法使用自定义形状判断点击区域,确保只有组件可视范围内的区域会响应鼠标事件。 - 渲染优化:使用
Graphics2D进行绘制,提升渲染质量,同时通过create()和dispose()避免资源泄漏。
使用方式
和原代码保持一致,传入需要的圆角大小即可:
JPanel user_icon = new RoundPanel(8); user_icon.setBackground(Color.decode("#363b41")); user_icon.setBorder(null); user_icon.setBounds(160, 135, 40, 46); container.add(user_icon); user_icon.setLayout(null);
内容的提问来源于stack exchange,提问作者Mohamed Gharib
相关产品推荐
相关产品推荐

