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

如何修复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();
        }
    }
}

关键修改说明

  1. 修正绘制坐标:使用insets.left和insets.top作为绘制起点,确保背景和进度条都在组件的内边距范围内,避免边缘裁切
  2. 优化进度条形状:
    • 进度未满时,绘制一个带有左侧圆角的矩形,通过裁剪(setClip)去掉右侧的圆角部分,保证右侧是直角
    • 进度100%时,恢复全圆角形状,和背景保持一致
  3. 添加抗锯齿:开启KEY_ANTIALIASING渲染提示,让圆角边缘更平滑
  4. 调整内边距:给组件添加少量内边距,彻底避免边缘裁切问题

内容的提问来源于stack exchange,提问作者spozzi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 20:59:59