2014-01-18 262 views
1

起初我写这个类DrawOval.java如下: -绘制椭圆

public class DrawOval extends JPanel{ 
    private int diameter = 10; 

    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     g.fillOval(10,10,diameter,diameter); 
    } 
    public void setDiameter(int newD){ 
     diameter = (newD>=0 ? newD : 10); 
     repaint(); 
    } 
    public Dimension getPreferredSize(){ 
     return new Dimension(200,200); 
    } 
    public Dimension getMinimumSize(){ 
     return getPreferredSize(); 
    } 
} 

然后我写这个类TheWindow.java如下: -

public class TheWindow extends JFrame{ 
    private DrawOval myPanel; 
    public TheWindow(){ 
     super("The title"); 
     myPanel = new DrawOval(); 
     myPanel.setBackground(Color.GREEN); 
     add(myPanel,BorderLayout.CENTER); 
    } 
} 

在最后我写了如下的主要类: -

public class Test{ 
    public static void main(String[] args){ 
     TheWindow w = new TheWindow(); 
     w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     w.setSize(300,300); 
     w.setVisible(true); 
    } 
} 

并且输出只是一个没有任何椭圆形的绿色背景的框架?

回答

1

你永远不会打电话setDiameter(...),所以该字段保持0值,并不会绘制椭圆。

一个解决方案是在每次创建DrawOval对象时尝试记住调用此方法,但为何强制自己记住这一点?而是使直径成为构造函数的参数,并确保该类没有默认构造函数,以便在创建对象时将直径字段必须设置为某个值。另一个选择是给直径字段一个默认值,以便即使它从未明确设置,它将始终被隐式设置。

0

您应该调用setDiameter方法来绘制椭圆形状。 但我认为你应该将此方法与paintComponent合并。通过这种方式,你不应该关心调用方法。

我的意思是:

public void paintComponent(Graphics g, int newD){ 

    super.paintComponent(g); 

    diameter = (newD>=0 ? newD : 10); 
    repaint();   

    g.fillOval(10,10,diameter,diameter); 

} 
+0

请澄清:合并有什么的paintComponent? –

+0

我的意思是你应该把setDiameter方法的代码放在paintComponent中。您不需要单独的方法来完成此任务。这样你就不需要调用这个方法。我会编辑我的答案,看看我的意思。 –

+0

更好地给直径一个默认值,并且永远不要**在'paint(Graphics g)'或'paintComponent(Graphics g)'方法内部调用'repaint()'。永远。这有潜在的递归和/或不良副作用的风险。只是不要这样做或推荐这个。 –