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
相关产品推荐
相关产品推荐

