Hello All,

I'm trying to create three independent animations that all occur in one main frame. I have to use the following methods in my code

--- Animate ---
public interface Animate {
    void move( double x, double y);
    void changeConfiguration();
}

--- Drawable -----
import java.awt.Graphics2D;

public interface Drawable {
    void draw(Graphics2D g2d);
}

However i'm having a bit of trouble figuring out where, and how i'm suppose to implement them in my code

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Color;
import javax.swing.JComponent;

public class ObjectA extends JComponent{
    public void paintComponent( Graphics g ){
	Graphics2D g2 = (Graphics2D) g;
	Rectangle box1a = new Rectangle(50, 50, 100, 100);
	Rectangle box1b = new Rectangle(75, 75, 50, 50);
	Rectangle box2a = new Rectangle(350, 350, 100, 100);
	Rectangle box2b = new Rectangle(375, 375, 50, 50);
	g2.setPaint( Color.blue );
	g2.fill( box1a );
	g2.fill( box2a );
	g2.setPaint( Color.red );
	g2.fill( box1b );
	g2.fill( box2b );
    }
}

What i need to happen is for the two rectangles to move back and forth across frame horizontally, therefore i'm told to use the Animate method, (above) however, i can't seem to get it to work for me. I also need to create a class to call on the Object to show the animation, which i'm also having some issues with, any advice?

Recommended Answers

All 53 Replies

the two rectangles to move back and forth across frame horizontally

To move horizontally you need to change the x values. Your code has the locations hardcoded.
The variables created in a method disappear when the method exits.
You should define the shapes outside of the paintComponent method where they are visible to the painting method and to other methods that will change there position.
How do you want to change the shapes' locations? User input or timer or what?

You need to create three objects to represent the three moving shapes (using a new class that you have to define). Each object must implement the Animate interface. Your main animation class can then call each object's move method to move it (eg on a Timer), and your main paintComponent method calls each object's draw method to get them drawn.

So if i gave a final int value for x and y, say both 0 and 0, then gave my rectangles values relative to the starting point, so instead of this

Rectangle box1a = new Rectangle(50, 50, 100, 100);
Rectangle box1b = new Rectangle(75, 75, 50, 50);
Rectangle box2a = new Rectangle(350, 350, 100, 100);
Rectangle box2b = new Rectangle(375, 375, 50, 50);

have something like this

Rectangle box1a = new Rectangle(x + 50, y + 50, 100, 100);
Rectangle box1b = new Rectangle(x + 75, y + 75, 50, 50);
Rectangle box2a = new Rectangle(x + 350, y + 350, 100, 100);
Rectangle box2b = new Rectangle(x + 375, y + 375, 50, 50);

then they would be able to be moved since their coordinates aren't set?

The expressions x + 50 etc will be evaluated once, when the statement
Rectangle box1a = new Rectangle(x + 50, y + 50, 100, 100);
is executed, and will not change if you later change x, so no, that won't enable them to move.
Please refer to my previous post for the standard (and only sensible) way of doing this

So, are you saying i have to make 3 classes, one for each object, then I have to make three more classes to call on those objects in order to move them? Sorry, I'm a little confused about the whole thing

One class to represent "things that can be moved and drawn". Three instances of that class.
One master class that calls the move methods for those 3 instances to move them, and from in its paintComponent, calls their draw methods to draw them.

So three classes
ObjectA, ObjectB and ObjectC
in those classes i'll have the objects drawn and how i want them to move,
then in the "Master Class" have the code to call on the three Object Classes, make them move, then redraw them?

It seems i completely shit the bed here,
might as well try and start from scratch.

Don't confuse classes and objects (ie instances of classes). You need just one class that has the variables and code to move and draw a single rectangle (or whatever). You create three instances of this one class, so each has its own position, speed etc, but they all share the same code for move and draw.
And yes, it may be easier to start again, and just copy over bits of code where it ca be reused.

So in my ObjectA, i'll put the classes required to construct, draw and move a rectangle?

If so, then building from this class is there anything salvageable?

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Color;
import javax.swing.JComponent;

public class ObjectA extends JComponent{
    private int x = 0;
    private int y = 0;
    public void paintComponent( Graphics2D g2d ){
	Rectangle2D.Double box1a = new Rectangle2D.Double (x + 50, y + 50, 100, 100);
	Rectangle2D.Double box1b = new Rectangle2D.Double (x + 75, y + 75, 50, 50);
	Rectangle2D.Double box2a = new Rectangle2D.Double (x + 350, y + 350, 100, 100);
	Rectangle2D.Double box2b = new Rectangle2D.Double (x + 375, y + 375, 50, 50);
	g2d.setPaint( Color.blue );
	g2d.fill( box1a );
	g2d.fill( box2a );
	g2d.setPaint( Color.red );
	g2d.fill( box1b );
	g2d.fill( box2b );
    }
}

i know the draw method isn't there, but whenever i try to load it i get upwards of 30 or so errors

Scratch that, I've decided it's better off starting over then trying to salvage that code.

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Color;
import javax.swing.JComponent;

public class ObjectA extends JComponent{
    public interface Drawable {
        void draw(Graphics2D g2d)
        // Creation of Shapes go here
    }
	
    public interface Animate {
        void move( double x, double y);
        // Simple x and y coordinates for moving the shape go here
    }
}

You can keep that quite lot simpler, along these lines...

public class AmnimatedObject {
  // private vars for position, speed, direction, size, color,  as required
  // constructor
  // set methods for speed etc
  public void move() {
    // update position  according to speed, direction etc
  }
  public void draw(Graphics2d g) {
    // draw according to position, size, color etc
    g2d.setPaint(color);
    g2d.fill( ...
  }
}

Then you can create as many as you want:

AnimatedObject object1 = new AnimatedObject(size, initial position...);
AnimatedObject object2 = new AnimatedObject(size, initial position...);
...

and in your main paintComponent method you can ask the objects to draw themselves...

object1.draw(g2d);
object2.draw(g2d);
...

Do you need the implements on the class def?

There's no need to have the interfaces at all, just define the public methods in the class.
If you want to get really smart you make the class abstract with the draw method abstract, then create subclasses for different shapes etc that differ only in their draw method implemenattions. (Not in this case)

public class AmnimatedObject {
  // private vars for position, speed, direction, size, color,  as required
    private int x = 0;
    private int BIG_BOX = 100;
    private int SMALL_BOX = 50;
    private string color = blue;
  // set methods for speed etc
  public void move(double dx, double dy) {
    // update position  according to speed, direction etc
  }
  public void draw(Graphics2d g) {
    // draw according to position, size, color etc
    Rectangle2D.Double BOX1 = new Rectangle2D.Double(x + 50, y + 50, BIG_BOX, BIG_BOX);
    g2d.setPaint(color);
    g2d.fill( BOX1 );
  }
}

So when you say speed, and direction, what would i fill in for that?

@Hypnos:
You don't need any parameters for the move method - each object knows its own position (x,y) already. You just need to call move at regular intervals and let each object update its own x and y accordingly.

(just saw your post):
By "speed" I mean the amount by which x (or y) changes each time move is called, so if x starts as 0 and speed is 5, then as move is called each time x will go 0, 5, 10, 15... and thus move across the screen.
Direction is a combination of how much you change x and y each move, eg change x by 0, y by -10, object will move upwards.

Okay, so the move
Alright then i understand!

So with move, i would have to make some sort of loop so that it knows where the borders are though wouldn't i? How can i make it so that it just goes right when it can, then stop at a certain point and turn around?

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Color;
import javax.swing.JComponent;

public class AmnimatedObject {
  // private vars for position, speed, direction, size, color,  as required
    private int x = 0;
    private int BIG_BOX = 100;
    private int SMALL_BOX = 50;
    private string color = blue;
    private Xspeed = 5.0;
    private Yspeed = 5.0;
  public void move() {
    // update position  according to speed, direction etc
  }
  public void draw(Graphics2d g) {
    // draw according to position, size, color etc
    Rectangle2D.Double BOX1 = new Rectangle2D.Double(x + 50, y + 50, BIG_BOX, BIG_BOX);
    g2d.setPaint(color);
    g2d.fill( BOX1 );
  }
}

My Code thus far for nit-picking

no :

private int BIG_BOX = 100;
private int SMALL_BOX = 50;

in the animatedObject Class you only want general variables that would apply to any object of that class, like width and heigth, the small and big values are gonna be assigned separatly on 2 AnimatedObject objects in your main method.

OK, Borders next.
You need some kind of variable or method that tells you where the border is. Maybe depends on the size of the JPanel, but you could use a constant for now. and implement it properly later.
Then in your move method you update x, then if it's reached the border, you simply reverse it's speed (Xspeed = - Xspeed) so it starts moving backwards. In general you do that 4 times, ie for x hitting the left or right border, and y hitting the top or bottom border.
NitPicking:
watch the capitalisation of your names. xSpeed rrather than Xspeed becuase vars and methods should begin with lower case. And if BIG_BOX is a constant, as implied by its capitalisation, declare it final.

I'm finishing now, but I'll check this thread in the morning.

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Color;
import javax.swing.JComponent;

public class AmnimatedObject {
    private int x = 0;
    private int BIG_BOX = 100;
    private int SMALL_BOX = 50;
    private string color = blue;
    private xSpeed = 5.0;
  public void move() {
    x = x + xSpeed;
    if (x + BIG_BOX = 450){
	xSpeed = -xSpeed
    }
    else if (x = 50){
	xSpeed = xSpeed
    }
  }
  public void draw(Graphics2d g) {
    Rectangle2D.Double BOX1 = new Rectangle2D.Double(x + 50, 50, BIG_BOX, BIG_BOX);
    g2d.setPaint(color);
    g2d.fill( BOX1 );
    repaint();
  }
}

This is what i have for a Blue square to bounce back and forth along the top of a frame. Please tell me it actually does this...

no, 1 square is 1 AnimatedObject's object.

program that class like it IS one square, then in your main program, you will be able to create four or five or 10000 squares using 10000 times the class AnimatedObject.

You should not call repaint in the draw method. That would tend to create an infinite loop.
repaint -> paint -> draw -> repaint etc

The box could be defined outside of the draw method (as a class variable) and given a value in the move method where the value of x is changed.

At this point with your project I would write a simple testing program that extends JFrame and adds a class of yours that extends JPanel. Override its paintComponent method and call the draw method in your AnimatedObject class to see if it draws as you expect.
Later you can add a Timer to call the move method and have the box move.

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

public class ObjectA {
    private int x = 0;
    private int Width = 100;
    private int Height = 100;
    private static Color Box_Color = Color.BLUE;
    private int xSpeed = 5;
  public void move() {
    if (x + Width == 450){
	xSpeed = -xSpeed;
    }
    else if (x == 50){
	xSpeed = xSpeed;
    }
    x = x + xSpeed;
  }
  public void draw(Graphics2D g2d) {
    Rectangle2D.Double BOX1 = new Rectangle2D.Double(x + 50, 50, Width, Height);
    g2d.setPaint(Box_Color);
    g2d.fill( BOX1 );
  }
}

My Prof gave me a program to base the "Master Object" (the program that shows all the animations) I think i've reduced it down to what i might need to get this to work.

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.EventQueue;
import javax.swing.JPanel;
import javax.swing.JFrame;

public class ThreeObjectAnimation extends JPanel implements ActionListener {

    private javax.swing.Timer timer;

    private int width = -1;
    private int height = -1;

    public ThreeObjectAnimation() {
        setPreferredSize(new Dimension( 500, 500 ) );
        setBackground( Color.White );

        timer = new javax.swing.Timer(250, this);
        start();
    }
    public void start(){
	timer.start();
    }
    public void stop(){
	timer.stop();

    public void actionPerformed( ActionEvent evt ) {
	BOX1.move(300,0);
        repaint();
    }

    public static void main(String[] args){
	JFrame frame = new JFrame();
	ObjectA A = new ObjectA;
	frame.setSize(500, 500);
	frame.setTitle( "Three_Object_Animation.jpg" );
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.add( A );
	frame.setVisible( true );
    }
}

What happens when you compile and execute the code?

ObjectA is not a very descriptive name for the class.

I have to call the three class ObjectA, ObjectB, and ObjectC. it's one of the rules in the question. When i try and run it i get flooded with errors that i can't seem to fix, cause they don't make sense

public void actionPerformed( ActionEvent evt ) {
	BOX1.move(300,0);
        repaint();
    }

heres 2 that are easy to fix...

BOX1 is a Rectangle object you declare localy in ObjectA's draw method, so it's out of scope here.

move() method does not take any arguments.

edit : also in move() dont use == to compare x and the margin , use >= or <= so if you go over it won't keep going.

Before you add all of the other classes, you need to get a simple one working.
I suggested earlier that you make the minimum program to test that the ObjectA class will display itself in the GUI.
I make that same suggestion again. Start with a simple program and get it to work first.
THEN start adding features.

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.Color;
import javax.swing.JPanel;

public class ObjectA extends JPanel{
    private int x = 0;
    private int Width = 100;
    private int Height = 100;
    private static Color Box_Color = Color.BLUE;
    private int xSpeed = 5;
  public void move() {
    if (x + Width >= 450){
	xSpeed = -xSpeed;
    }
    else if (x <= 50){
	xSpeed = xSpeed;
    }
    x = x + xSpeed;
  }
  public void draw(Graphics2D g2d) {
    Rectangle2D.Double BOX1 = new Rectangle2D.Double(x + 50, 50, Width, Height);
    g2d.setPaint(Box_Color);
    g2d.fill( BOX1 );
  }
}

I tried making something to see if my drawing worked
But got a blank frame...

import javax.swing.JFrame;

public class ThreeObjectAnimation {
    public static void main(String[] args){
	JFrame frame = new JFrame();
	frame.setSize(500, 500);
	frame.setTitle( "Three_Object_Animation.jpg" );
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	ObjectA TEST = new ObjectA();
	frame.add(TEST);
	frame.setVisible( true );
    }
}

Don't really know why.

Is the draw method being called? Add a println to it to see if it is executed.
You missed reading all of my previous message:

At this point with your project I would write a simple testing program that extends JFrame and adds a class of yours that extends JPanel. Override its paintComponent method and call the draw method in your ... class to see if it draws as you expect.

Alright, what do i have to do Override it's PaintComponent then?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.