2

Basically, I have an interface Shape that has a draw() and animate() method. Each class that will draw a shape implements this. There's another class that contains an arrayList of those Shape classes. And then there's a separate class that contains my JFrame. I have an "Animate" button that calls all the animate() method in that arrayList.

I'm using netbeans and it's saying that I have no errors. The draw() method works perfectly. It's the animation that I'm having problem with. I've debugged it and apparently, the repaint() method doesn't call anything else and that's why none of the shapes animates/moves. It can't find the draw() method and therefore, doesn't redraw it.

Here's my code:

This is one of my shapes

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();
    } 
}

This contains my arrayList of Shapes

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

I've tried having a JPanel or JLayeredPane, tried using revalidate(), validate(), even invalidate(). Many advised having a paintComponent() that calls super.paintComponent(), but is there any way to do it without removing/replacing draw() method?? Although, I could just be missing some little important detail . . .

Apparently, a lot of people have already asked this here and I've read most of them. I apologize for being redundant. But any help or advice is greatly appreciated!

EDIT: I fixed it! Thank you, guys!

user3140026
  • 135
  • 10
  • 2
    why would it call draw? The Java paint chain is repaint() -> update() -> paint(), so if you aren't overwriting paint, not much will happen? – Mike 'Pomax' Kamermans Dec 27 '13 at 17:50
  • 1
    Why AWT rather than Swing? See my answer on [Swing extras over AWT](http://stackoverflow.com/a/6255978/418556) for many good reasons to abandon using AWT components. If you need to support older AWT based APIs, see [Mixing Heavyweight and Lightweight Components](http://www.oracle.com/technetwork/articles/java/mixing-components-433992.html). – Andrew Thompson Dec 27 '13 at 23:45

2 Answers2

0

From my understanding, (which is limited to the class I took last semester) you need to override paintComponent and call the draw function of the sub-components. repaint() calls paintComponent.

Here is the example code from my prof last semester. I find his code very clear and easy to pull from. http://students.cs.byu.edu/~cs240ta/fall2013/rodham_files/week-09/graphics-programming/code/Drawing/src/noevents/DrawingComponent.java

qzcx
  • 361
  • 1
  • 12
0

I realize your edit says you've fixed it but I wanted to make sure and point out the issue with the code in the OP. Circle, as far as I can tell, should not be extending Canvas. In animate, it calls repaint, but the repaint goes nowhere because it has not been added anywhere as a component.

A correction would look something like this:

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();
    }
}

And as a side note, I also agree with @AndrewThompson that there is little reason to use AWT over Swing. Especially if you are trying to mix the two, don't.

Radiodef
  • 37,180
  • 14
  • 90
  • 125