首页 > 解决方案 > 尽管使用了合乎逻辑的方式,但无法绘制圆圈

问题描述

我尝试使用 java awt 绘制一个圆圈,我在输出中得到的只是几个小圆圈,它们相隔很远,而且看起来不像一个整体。代码如下:

class DrawFrame extends JFrame {
    int хс, yc, r, x, y;
    float p;
    DrawFrame(int rr, int c1, int c2) {
        setSize(1000, 1000);
        setTitle("circle drawing algo");
        r = rr;
        xc = c1;
        yc = c2;
    }
    public void paint(Graphics g) {
        Circl(g);
    }
    public void Circl(Graphics g) {
        x = xc - r;
        while (x <= (xc + r)) {
            for (y = yc - r; y <= (yc + r); y++) {
                p = x * x + y * y - r * r;
                if (p == 0.0)
                    g.drawOval(x, y, 2, 2);
            }
            x++;
        }
    }

标签: javaswingjava-2d

解决方案


您应该首先阅读在 AWT 和 Swing中执行自定义绘画和绘画,以更好地了解绘画系统的工作原理以及您应该如何使用它。

您不应该覆盖paint顶级组件的方法,除了没有被双缓冲外,它们实际上是复合组件。这意味着它们上面放置了许多额外的组件,这些组件提供了窗口的整体功能。

JRootPane 它有很多层

这意味着您在框架表面上绘制的内容可能会被忽略,因为它上面的内容会覆盖在它上面。

您还忽略了绘制过程的复杂性,除非您准备自己承担该paint方法的责任,否则您应该始终调用它的super方法。

一个更好的起点是 a JPanel(更简单)并覆盖它的paintComponent方法

例子

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane(100, 100, 100));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        int xc, yc, r;

        public TestPane(int rr, int c1, int c2) {
            r = rr;
            xc = c1;
            yc = c2;
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(r * 2, r * 2);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            circle(g);
        }

        public void circle(Graphics g) {
            // Credit to LAD for the algorithm updates
            int x = xc - r;
            while (x <= (xc + r)) {
                for (int y = yc - r; y <= (yc + r); y++) {
                    float p = (x - xc) * (x - xc) + (y - yc) * (y - yc) - (r * r);
                    if (p <= 0.0f)
                    {
                        g.drawOval(x, y, 2, 2);
                    }
                }
                x++;
            }


        }
    }

}

归功于 LAD 的算法更新


推荐阅读