Repaint()方法不调用draw()

时间:2013-12-27 17:34:19

标签: java awt paint repaint

基本上,我的界面形状有draw()animate()方法。每个绘制形状的类都实现了这一点。还有另一个类包含这些Shape类的arrayList。然后是一个包含我的JFrame的单独类。我有一个“动画”按钮,可以调用animate()中的所有arrayList方法。

我正在使用netbeans而且它说我没有错误。 draw()方法非常有效。这是我遇到问题的动画。我调试了它,显然,repaint()方法没有调用任何其他东西,这就是为什么没有形状动画/移动的原因。它无法找到draw()方法,因此不会重绘它。

这是我的代码:

这是我的形状之一

public class Circle extends Canvas implements Shape{
    int xpos, ypos, diam;
    GradientPaint color;
    public Circle(){
        xpos = 103;
        ypos = 88;
        diam = 140;
        color = new GradientPaint(0, 0, new Color(204, 204, 254), 
                                  120, 100, new   Color(255, 255, 255), true);
    }

    @Override
    public void draw(Graphics g){
       Graphics2D g2 = (Graphics2D)g;
       g2.setPaint(color);
       g.fillOval(xpos, ypos, diam, diam); 
    }

    @Override
    public void animate(){
       xpos += 10;
       ypos += 10;
       repaint();
    } 
}

这包含我的形状的arrayList     

public class ShapeCanvas extends Canvas {
    private ArrayList list;
    public ShapeCanvas(){
        setBackground(Color.WHITE);
        setSize(1000, 700);
        list = new ArrayList<>();
        Circle circle = new Circle();
        list.add(circle);

}

//calls all draw() method
@Override
public void paint(Graphics g){
    for (int i = 0; i < list.size(); i++){
            list.get(i).draw(g);
    }
}

//this method calls all animate() method
public void animateAll(){
    for (int i = 0; i < list.size(); i++){
                list.get(i).animate();
    }
 }

}

And this here is my JFrame

public class Animation extends JFrame{ public Animation(){ setLayout(new BorderLayout()); final ShapeCanvas sc = new ShapeCanvas(); JButton animate = new JButton("Animate"); animate.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent ae){ sc.animateAll(); } }); add(sc, "Center"); add(animate, "South"); } public static void main(String[] args) { Animation g = new Animation(); g.setVisible(true); g.setSize( 1000, 700 ); g.setTitle( "Animation" ); g.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); g.setResizable(false); } }

我尝试使用JPanelJLayeredPane,尝试使用revalidate(),validate(),甚至是invalidate()。许多人建议使用一个调用super.paintComponent()的paintComponent(),但有没有办法在不删除/替换draw()方法的情况下执行它?虽然,我可能只是缺少一些重要的细节。 。

显然,很多人已经在这里问过这个问题,而且我已经阅读了大部分内容。我为多余而道歉。但是非常感谢任何帮助或建议!

编辑: 我修好了它! 谢谢你们,伙计们!

2 个答案:

答案 0 :(得分:0)

根据我的理解,(这仅限于我上学期的课程) 你需要覆盖paintComponent并调用子组件的draw函数。 repaint()调用paintComponent。

以下是我上一学期教授的示例代码。我发现他的代码非常清晰,易于理解。 http://students.cs.byu.edu/~cs240ta/fall2013/rodham_files/week-09/graphics-programming/code/Drawing/src/noevents/DrawingComponent.java

答案 1 :(得分:0)

我意识到你的编辑说你已经修复了它但我想确定并指出OP中代码的问题。据我所知,Circle不应该延伸Canvas。在动画中,它会调用重绘,但重绘无处可去,因为它没有作为组件添加到任何地方。

修正看起来像这样:

class Circle implements Shape {
    @Override
    void animate() {
        /* only set positions */
    }
}

class ShapeCanvas extends Canvas {
    @Override
    void animateAll() {
        for(/* all shapes */) {
            /* call shape.animate() */
        }

        /* repaint this Canvas */
        repaint();
    }
}

作为旁注,我也同意@AndrewThompson认为没有理由在Swing上使用AWT。特别是如果你想要混合两者,不要。