2014-09-21 80 views
4

我一直試着找到解決這個問題的方法,但我似乎無法理解如何解決它。根據Java中的用戶輸入繪製一個圓圈

我試圖寫一個簡單的程序來繪製這些規範程序中的循環:

  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的回答

Circle類

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); 
       */ 
      } 
     }); 

    } 

} 

回答

5

在你無參數的構造函數Circle,你要創建一個sphere (默認Ellipse2D.Double),然後獲取值。您應該創建在這些值sphere基於,你是在這三個參數的構造函數

Ellipse2D.Double

Ellipse2D.Double()
構造一個新Ellipse2D的,初始化爲:位置(0,0)和大小(0,0)。

另一個設計可能性

  1. 已經在CirclesetSphere方法,你可以設置橢圓和重繪

    public void setSphere(Ellepse2D.Double sphere) { 
        this.sphere = sphere; 
        repaint(); 
    } 
    
  2. 貴公司的所有JOptionPane還是後顯示框架。看起來正確。然後,當您獲得這些值時,您可以撥打Circle類的setSphere,並帶上一個新的Ellipse2D.Double,它將顯示在面板中。

其他注意事項:

  • 在做風俗畫,更好地覆蓋塗組件getPreferredSize(),並調用框架pack(),而不是setSize()

  • 見初始線程。 Swing應用程序應該在「事件調度線程」上啓動。

  • 此外,您不需要在Circle類中多餘的x, y, etc值。它們已經被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); 
    } 
} 

UPDATE

我想知道我怎麼可以把JOptionPane在public void inputX(),public void inputY()和public void inputRadius()下請求Circle類中的用戶輸入,然後在CircleTester類中調用main中的那些輸入?

你可以做的只是在每個方法中調用JOPtionPane。假設你只想得到x,然後調用JOptionPane,並基於該值,使用舊的值從舊的Ellipse中創建一個新的Ellipse,並使用新的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); 
} 

你可以做到這一點,其他人也是如此。這樣,當你調用方法時,一旦你輸入,它只會改變一個變量。

你也可以有一種方法來獲得所有的變量,就像我在我的例子中那樣。

+0

謝謝你的幫助!這工作!我想知道如何將JOptionPane請求在public class inputX(),public void inputY()和public void inputRadius()下的Circle類中的用戶輸入,然後在CircleTester類的main中調用它們?你可以查看上面的代碼,看看我在說什麼。 – user3768057 2014-09-21 13:25:09

+0

你可以做的只是在每種方法中調用'JOPtionPane'。假設你只想得到x,然後調用JOptionPane,並基於該值,使用舊的值從舊的Ellipse中創建一個新的Ellipse,並使用新的x。然後調用'setSphere'。給我一分鐘的例子 – 2014-09-21 13:33:01

+0

看我的**更新** – 2014-09-21 13:37:56

3
  1. 從Circle類中獲取所有UI,即刪除所有這些JOptionPane調用。
  2. 相反,所有用戶交互應該在您的CircleTester類中。
  3. Circle類應該不是專注於用戶IO,而只是繪製由其屬性定義的Circle。
  4. 爲您的Circle類提供一個構造函數,該構造函數接受有意義的參數。
  5. 在我看來,Ellipse2D不是必需的,因爲您可以通過調用g.drawOval(....)簡單地繪製一個Graphics對象的圓,從而簡化您的程序。
  6. 當您在CircleTester中獲得輸入參數後,創建傳入從CircleTest獲得的參數的Circle對象,並顯示您的Circle。
  7. 此外,不要忘記調用paintComponent方法覆蓋內的super.paintComponent(g)方法。
  8. 小挑逗,但我不會聲明周長和麪積變量,而是給你的Circle類getCircumference()getArea()方法,當需要的時候可以現場計算這些方法。否則,如果你給Circle一個setRadius(...)方法,你必須記住改變setter方法中的其他字段,並且如果你使radius或其他字段公開,所有的heck都可以打破。玩安全,只爲這兩個屬性,而不是字段accessor方法。