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

Java Swing绘制24等分带编号彩色圆环的显示问题求助

Java Swing 圆环绘制问题与解决

我试图用Java Swing绘制一个被等分为24个扇区的圆环,每个扇区填充不同颜色并标注1至24的对应编号,但遇到以下显示问题:

  • 初始代码仅能显示13至24的编号
  • 若将遍历条件改为仅12个编号,编号可显示但扇区无填充色

初始代码

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

public class DividedCircleWithColorsAndNumbersExample extends JFrame {
    private final Color[] segmentColors = {
            Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.ORANGE, Color.CYAN,
            Color.MAGENTA, Color.PINK, Color.LIGHT_GRAY, Color.DARK_GRAY, Color.GRAY,
            Color.BLACK, Color.CYAN, Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,
            Color.ORANGE, Color.CYAN, Color.MAGENTA, Color.PINK, Color.LIGHT_GRAY,
            Color.DARK_GRAY, Color.GRAY, Color.BLACK
    };

    public DividedCircleWithColorsAndNumbersExample() {
        setTitle("Divided Circle with Colors and Numbers Example");
        setSize(400, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        Graphics2D g2d = (Graphics2D) g;

        int centerX = getWidth() / 2;
        int centerY = getHeight() / 2;
        int radius = 150;

        int x = centerX - radius;
        int y = centerY - radius;
        int diameter = 2 * radius;

        double angle = 2 * Math.PI / 24; // 每个扇区间的夹角

        for (int i = 0; i < 24; i++) {
            g2d.setColor(segmentColors[i]);
            int startAngle = (int) Math.toDegrees(i * angle);
            int arcAngle = (int) Math.toDegrees(angle);
            g2d.fillArc(x, y, diameter, diameter, startAngle, arcAngle);

            g2d.setColor(Color.WHITE);
            Font font = new Font("Arial", Font.BOLD, 16);
            g2d.setFont(font);

            int labelRadius = radius - 30;
            int labelX = (int) (centerX + labelRadius * Math.cos(i * angle + angle / 2));
            int labelY = (int) (centerY + labelRadius * Math.sin(i * angle + angle / 2));
            drawCenteredString(g2d, String.valueOf(i + 1), labelX, labelY);
        }
    }

    private void drawCenteredString(Graphics2D g2d, String text, int x, int y) {
        FontMetrics fm = g2d.getFontMetrics();
        int textWidth = fm.stringWidth(text);
        int textHeight = fm.getHeight();
        g2d.drawString(text, x - textWidth / 2, y + textHeight / 4);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new DividedCircleWithColorsAndNumbersExample();
        });
    }
}

问题解决:拆分绘制循环

将扇区填充与编号绘制拆分为两个独立循环后,问题得以解决(推测原因是扇区填充操作覆盖了之前绘制的编号)。对应代码如下:

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

public class DividedCircleWithColorsAndNumbersExample extends JFrame {

    private final Color[] segmentColors = {
        Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.ORANGE, Color.CYAN,
        Color.MAGENTA, Color.PINK, Color.LIGHT_GRAY, Color.DARK_GRAY, Color.GRAY,
        Color.BLACK, Color.WHITE, Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,
        Color.ORANGE, Color.CYAN, Color.MAGENTA, Color.PINK, Color.LIGHT_GRAY,
        Color.DARK_GRAY, Color.GRAY, Color.BLACK
    };

    public DividedCircleWithColorsAndNumbersExample() {
        setTitle("Divided Circle with Colors and Numbers Example");
        setSize(400, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
//        setExtendedState(JFrame.MAXIMIZED_BOTH);
        setVisible(true);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        Graphics2D g2d = (Graphics2D) g;

        int centerX = getWidth() / 2;
        int centerY = getHeight() / 2;
        int radius = 150;

        int x = centerX - radius;
        int y = centerY - radius;
        int diameter = 2 * radius;

        double angle = 2 * Math.PI / 24; // 每个扇区间的夹角

        // 先绘制所有扇区
        for (int i = 0; i < 24; i++) {
            g2d.setColor(segmentColors[i]);
            int startAngle = (int) Math.toDegrees(i * angle);
            int arcAngle = (int) Math.toDegrees(angle);
            g2d.fillArc(x, y, diameter, diameter, startAngle, arcAngle);
        }

        // 再绘制所有编号
        for (int i = 0; i < 24; i++) {
            g2d.setColor(Color.black);
            Font font = new Font("Arial", Font.BOLD, 16);
            g2d.setFont(font);

            int labelRadius = radius - 30;
            int labelX = (int) (centerX + labelRadius * Math.cos(i * angle + angle / 2));
            int labelY = (int) (centerY + labelRadius * Math.sin(i * angle + angle / 2));
            drawCenteredString(g2d, String.valueOf(i + 1), labelX, labelY);
        }
    }

    private void drawCenteredString(Graphics2D g2d, String text, int x, int y) {
        FontMetrics fm = g2d.getFontMetrics();
        int textWidth = fm.stringWidth(text);
        int textHeight = fm.getHeight();
        g2d.drawString(text, x - textWidth / 2, y + textHeight / 4);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new DividedCircleWithColorsAndNumbersExample();
        });
    }
}

坐标优化调整

参考建议调整Y轴坐标计算逻辑后的代码如下:

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

public class DividedCircleWithColorsAndNumbersExample extends JFrame {
    private final Color[] segmentColors = {
            Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.ORANGE, Color.CYAN,
            Color.MAGENTA, Color.PINK, Color.LIGHT_GRAY, Color.DARK_GRAY, Color.GRAY,
            Color.BLACK, Color.WHITE, Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,
            Color.ORANGE, Color.CYAN, Color.MAGENTA, Color.PINK, Color.LIGHT_GRAY,
            Color.DARK_GRAY, Color.GRAY, Color.BLACK
    };

    public DividedCircleWithColorsAndNumbersExample() {
        setTitle("Divided Circle with Colors and Numbers Example");
        setSize(400, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
//        setExtendedState(JFrame.MAXIMIZED_BOTH);
        setVisible(true);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        Graphics2D g2d = (Graphics2D) g;

        int centerX = getWidth() / 2;
        int centerY = getHeight() / 2;
        int radius = 150;

        int x = centerX - radius;
        int y = centerY - radius;
        int diameter = 2 * radius;

        double angle = 2 * Math.PI / 24; // 每个扇区间的夹角

        for (int i = 0; i < 24; i++) {
            g2d.setColor(segmentColors[i]);
            int startAngle = (int) Math.toDegrees(i * angle);
            int arcAngle = (int) Math.toDegrees(angle);
            g2d.fillArc(x, y, diameter, diameter, startAngle, arcAngle);

            g2d.setColor(Color.black);
            Font font = new Font("Arial", Font.BOLD, 16);
            g2d.setFont(font);

            int labelRadius = radius - 30;
            int labelX = (int) (centerX + labelRadius * Math.cos(i * angle + angle / 2));
            // 调整Y轴方向,修正坐标原点差异
            int labelY = (int) (centerY + labelRadius * Math.sin(i * angle + angle / 2) * (-1));
            drawCenteredString(g2d, String.valueOf(i + 1), labelX, labelY);
        }
    }

    private void drawCenteredString(Graphics2D g2d, String text, int x, int y) {
        FontMetrics fm = g2d.getFontMetrics();
        int textWidth = fm.stringWidth(text);
        int textHeight = fm.getHeight();
        g2d.drawString(text, x - textWidth / 2, y + textHeight / 4);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new DividedCircleWithColorsAndNumbersExample();
        });
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 14:15:06