如何修复RoundRectangle2D绘制圆角JProgressBar时的左右不对称问题?
修复JProgressBar圆角不对称问题
你的圆角进度条出现左右不对称的问题,核心原因有两个:
- 绘制时未正确应用组件内边距,导致右侧圆角被容器边缘裁切
- 进度未满时,进度条右侧错误保留了圆角,不符合视觉逻辑(只有进度100%时,右侧才应该显示圆角)
以下是修复后的完整代码:
import javax.swing.*; import javax.swing.plaf.basic.BasicProgressBarUI; import java.awt.*; import java.awt.geom.RoundRectangle2D; public class RoundedProgressBar extends JProgressBar { public RoundedProgressBar() { setOpaque(false); setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); // 适当增加内边距避免裁切 setUI(new RoundedProgressBarUI()); } private class RoundedProgressBarUI extends BasicProgressBarUI { private static final int ARC_SIZE = 10; @Override protected void paintDeterminate(Graphics g, JComponent c) { Graphics2D g2 = (Graphics2D) g.create(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Insets insets = progressBar.getInsets(); int x = insets.left; int y = insets.top; int width = progressBar.getWidth() - insets.left - insets.right; int height = progressBar.getHeight() - insets.top - insets.bottom; // 绘制背景(全圆角) g2.setColor(progressBar.getBackground()); Shape backgroundShape = new RoundRectangle2D.Double(x, y, width, height, ARC_SIZE, ARC_SIZE); g2.fill(backgroundShape); // 计算进度宽度 int progressWidth = getAmountFull(insets, width, height); // 绘制进度条:未满时右侧直角,满时全圆角 g2.setColor(progressBar.getForeground()); Shape progressShape; if (progressWidth >= width) { progressShape = new RoundRectangle2D.Double(x, y, progressWidth, height, ARC_SIZE, ARC_SIZE); } else { // 左侧圆角,右侧直角 progressShape = new RoundRectangle2D.Double(x, y, progressWidth + ARC_SIZE/2, height, ARC_SIZE, ARC_SIZE); // 裁剪掉右侧多余的圆角部分 g2.setClip(new Rectangle(x, y, progressWidth, height)); } g2.fill(progressShape); g2.dispose(); } } }
关键修改说明
- 修正绘制坐标:使用
insets.left和insets.top作为绘制起点,确保背景和进度条都在组件的内边距范围内,避免边缘裁切 - 优化进度条形状:
- 进度未满时,绘制一个带有左侧圆角的矩形,通过裁剪(setClip)去掉右侧的圆角部分,保证右侧是直角
- 进度100%时,恢复全圆角形状,和背景保持一致
- 添加抗锯齿:开启
KEY_ANTIALIASING渲染提示,让圆角边缘更平滑 - 调整内边距:给组件添加少量内边距,彻底避免边缘裁切问题
内容的提问来源于stack exchange,提问作者spozzi
相关产品推荐
相关产品推荐

