java - 根据 Java 中的用户输入绘制圆圈

标签 java swing paintcomponent joptionpane

我一遍又一遍地尝试寻找解决这个问题的方法,但我似乎无法理解如何解决它。

我正在尝试编写一个简单的程序来在程序中使用这些规范绘制一个圆:

  1. 使用输入框 (JOptionPane) 向用户询问圆的半径。
  2. 在输入框 (JOptionPane) 中询问用户圆的 x 和 y 坐标。
  3. 计算圆的周长。
  4. 计算圆的面积。
  5. 在画圆的下方显示面积和周长。

不知怎的,它不会画圆,也不会计算周长和面积。你能帮我找到解决这个问题的办法吗?

这是我的代码:

--------主要--------

package circleSquarePackage;

import circleSquarePackage.Circle;

import javax.swing.JOptionPane;
import javax.swing.JFrame;

public class CircleTester {

    public static void main(String[] args) 
        {

        JFrame frame = new JFrame();

        // Display Circle in the frame
        frame.setSize(600, 500);
        frame.setTitle("CircleSquare");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Create Circle Components
        Circle round = new Circle();
        frame.add(round);

        frame.setVisible(true);

    }

}

--------其他类------------

package circleSquarePackage;

import javax.swing.JComponent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Ellipse2D.Double;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;

import javax.swing.JOptionPane;


public class Circle extends JComponent {
    // Member instance field
    private Ellipse2D.Double sphere;
    private int radius;
    double circumference, area;

    String x1; // starting x co-ordinate
    String y1; // starting y co-ordinate
    String r1; // radius for circle
    String draw;

    int x = 0;
    int y = 0;
    int r = 0;


    // Default constructor
    public Circle()
    {
        sphere = new Ellipse2D.Double();
    }

    // User defined constructor
    public Circle(int xAxis, int yAxis, int rad)
    {
        rad = r;
        xAxis = x;
        yAxis = y;
        sphere = new Ellipse2D.Double(xAxis, yAxis, rad, rad);
    }

    // Accessor methods
    public double calcCircumference()
    {
    return circumference = 2 * Math.PI * radius;
    }

    public double calcArea()
    {
        return area = Math.PI * radius * radius;
    }

    // Methods
    public void inputX()
    {
        x1 = JOptionPane.showInputDialog(null, "Input center (x value): ");
        x = Integer.parseInt(x1);
    }

    public void inputY()
    {
        y1 = JOptionPane.showInputDialog(null, "Input center (y value): ");
        y = Integer.parseInt(y1);

    }

    public void inputRadius()
    {
        r1 = JOptionPane.showInputDialog(null, "Input radius: ");
        r = Integer.parseInt(r1);
    }

    public void paintComponent(Graphics g)
    {
        // Cast 1D to 2D graphics
        Graphics2D g2 = (Graphics2D) g;

        g2.setColor(Color.BLUE); // set circle color to blue
        g2.fill(sphere);
        g2.draw(sphere);

        g2.setColor(Color.BLUE);
        g2.drawString("Circumference = " + calcCircumference(), 5, 450);
        g2.drawString("Area = " + calcCircumference(), 200, 450);
    }
}

根据 PEESKILLET 的回答更新

圈类

package circleSquarePackage;

import javax.swing.JComponent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Ellipse2D.Double;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JOptionPane;


public class Circle extends JComponent {
    // Member instance field
    private Ellipse2D.Double sphere;
    private int radius;
    double circumference, area;


    // Default constructor
    public Circle()
    {
        sphere = new Ellipse2D.Double();
    }

    public void setSphere(Ellipse2D.Double sphere) {
        this.sphere = sphere;
        repaint();
    }

    // User defined constructor
    public Circle(int xAxis, int yAxis, int rad)
    {
        sphere = new Ellipse2D.Double(xAxis, yAxis, rad, rad);
    }

    // Accessor methods
    public double calcCircumference()
    {
    return circumference = 2 * Math.PI * radius;
    }

    public double calcArea()
    {
        return area = Math.PI * radius * radius;
    }

    // Methods
    public void inputX()
    {
        int x = Integer.parseInt(JOptionPane.showInputDialog(null, "Enter x"));
        double y = sphere.y; // why is there a double y here when it asks for x?
        Ellipse2D.Double newSphere = new Ellipse2D.Double(x, y, size, size);
        setSphere(newSphere);
    }

    public void inputY()
    {
        int y = Integer.parseInt(JOptionPane.showInputDialog(null, "Enter y"));
        double x = sphere.x; 
        Ellipse2D.Double newSphere = new Ellipse2D.Double(x, y, size, size);
        setSphere(newSphere);
    }

    public void inputRadius() 
    {
        // is this how I do for radius?
        int r = Integer.parseInt(JOptionPane.showInputDialog(null, "Enter radius"));
        int size = r * 2;
        Ellipse2D.Double newSphere = new Ellipse2D.Double(x, y, size, size);
        setSphere(newSphere);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        g2.setColor(Color.BLUE); // set circle color to blue
        g2.fill(sphere);
        g2.draw(sphere);

        g2.drawString("Circumference: " + calcCircumference(), 5, 490);

    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(600, 500);
    }
}

-------- CircleTester类--------

package circleSquarePackage;

import circleSquarePackage.Circle;

import javax.swing.JOptionPane;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Ellipse2D.Double;

public class CircleTester {
    /*
    private static Ellipse2D.Double getCircle() {
        int x = Integer.parseInt(JOptionPane.showInputDialog(null, "Enter integer for x-coordinates:"));
        int y = Integer.parseInt(JOptionPane.showInputDialog(null, "Enter integer for y-coordinates:"));
        int radius = Integer.parseInt(JOptionPane.showInputDialog(null, "Enter radius of circle:"));
        int size = radius * 2;
        return new Ellipse2D.Double(x, y, size, size);
    }*/

    public static void main(String[] args) 
    {
        // Is there a way to call the inputX(), inputY(), and inputRadius() here?

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();


                frame.setTitle("CircleSquare");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                Circle round = new Circle();
                frame.add(round);

                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                /*
                Ellipse2D.Double newCircle = getCircle();
                round.setSphere(newCircle);
                */
            }
        });

    }

}

最佳答案

在您的无参数 Circle 构造函数中,您在获取值之前创建了一个 sphere(默认为 Ellipse2D.Double)。您应该根据这些值创建 sphere,就像您在三参数构造函数中一样

来自 Ellipse2D.Double

Ellipse2D.Double()
Constructs a new Ellipse2D, initialized to location (0, 0) and size (0, 0).

另一种设计可能性

  1. Circle类中有一个setSphere方法,可以设置椭圆和重绘

    public void setSphere(Ellepse2D.Double sphere) {
        this.sphere = sphere;
        repaint();
    }
    
  2. 在框架显示后仍然执行所有的 JOptionPane。似乎是对的。然后当你得到这些值时,你可以在 Circle 类上调用 setSphere,使用一个新的 Ellipse2D.Double 它将显示在面板中.

其他注意事项:

  • 在进行自定义绘制时,最好在绘制的组件上重写 getPreferredSize(),并在框架上调用 pack(),而不是 setSize()

  • 查看初始线程。 Swing 应用程序应该在事件调度线程上启动。

  • 此外,您不需要 Circle 类中的冗余 x、y 等 值。它们已经被 Ellipse 对象持有。如果您需要获取一些值,只需从中获取即可,即 sphere.xsphere.y.

这里是对我上面提到的建议的重构。 (您还需要做一些检查以确保数字确实是类型。我是懒惰)

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

public class CircleTester {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();

                frame.setTitle("CircleSquare");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                Circle round = new Circle();
                frame.add(round);

                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                Ellipse2D.Double newCircle = getCircle();
                round.setSphere(newCircle);
            }
        });

    }

    private static Ellipse2D.Double getCircle() {
        int x = Integer.parseInt(JOptionPane.showInputDialog(null, "Enter x"));
        int y = Integer.parseInt(JOptionPane.showInputDialog(null, "Enter x"));
        int radius = Integer.parseInt(JOptionPane.showInputDialog(null, "Enter x"));
        int size = radius * 2;
        return new Ellipse2D.Double(x, y, size, size);
    }
}

class Circle extends JComponent {

    private Ellipse2D.Double sphere;

    public Circle() {
        sphere = new Ellipse2D.Double();
    }

    public void setSphere(Ellipse2D.Double sphere) {
        this.sphere = sphere;
        repaint();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        g2.setColor(Color.BLUE); // set circle color to blue
        g2.fill(sphere);
        g2.draw(sphere);

    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(300, 300);
    }
}

更新

I was wondering how can I put the JOptionPane asking for user input in the Circle class under public void inputX(), public void inputY(), and public void inputRadius(), and then call those in the main in the CircleTester class?

您可以做的只是在每个方法中调用 JOPtionPane。假设您只想获取 x,然后调用 JOptionPane,并基于该值,使用旧值并仅使用新 x 从旧椭圆创建一个新椭圆。然后调用 setSphere。有点像

public void inputX() {
    int x = Integer.parseInt(JOptionPane.showInputDialog(null, "Enter x"));
    double y = sphere.y;
    double height = sphere.height;
    double width = sphere.width;
    Ellips2D.Double newSpehere = new Ellipse2D.Double(x, y, width, height);
    setSphere(newSphere);
}

您也可以这样做,其他人也可以这样做。这样,当你调用该方法时,一旦你输入,它只会改变一个变量。

您还可以使用一种方法来获取所有变量,就像我在示例中所做的那样。

关于java - 根据 Java 中的用户输入绘制圆圈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25956435/

相关文章:

java - 第一次打开 JDialog 时运行 KeyEventDispacther,然后将其删除

java - PaintComponent 未绘制到 JPanel 上

java - 在其他 JPanel 内重新绘制 JPanel

java - 在 Java 中重载

Java计算一段时间内两点之间的转变

java - Braintree 结账付款失败

java - JButton自定义问题

java - 是否可以有多个静态变量实例

Java Swing Timer Actionperformed 没有被调用

java - 在 Swing 中刷新 JTable 出现异常