-1

This is my frog class which is being called by a GUI class.

import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JLabel;

public class Frog implements Runnable {
    private int x, y, dx, dy;
    private int coordinates[]=new int[2];
    private boolean hungry;
    private JLabel jLabel;
    private ImageIcon image;
    private String name;

    public Frog() {

    }

    public  Frog(String name, boolean hungry) {
        image = new ImageIcon("images/frog.jpeg");
        jLabel = new JLabel(image);
        setName(name);
        setHungry(hungry);
        setCoordinates();
    }

    private void setName(String name) {
        this.name=name;
    }

    public int[] getCoordinates() {
        return coordinates;
    }

    public boolean isHungry() {
        return hungry;
    }

    public void setHungry(boolean hungry) {
        this.hungry = hungry;
    }

    public void display(Graphics paper) {
        paper.setColor(Color.black);
        paper.drawOval(x, y, dx, dx);
    }

    public void setCoordinates() {
        for(int i = 0; i < 2; i++) {
            Random rand = new Random();
            int p = rand.nextInt(100);
            coordinates[i] = p;
        }

        setX(coordinates[0]);
        setY(coordinates[1]);
    }

    public void move() {
        x = (int)Math.random() * 350;
        y = (int)Math.random() * 350;
        dx=20;
        dx=20;
        x += dx;
        y += dy;

        if (x > 800 || x < 0)
            dx=-dx;

        if (y > 600 || y < 0)
             dy=-dy;
    }

    public void setDx(int dx) {
        this.dx = dx;
    }

    public void setDy(int dy) {
        this.dy = dy;
    }

    public void setX(int x){
        this.x = x;
    }

    public void setY(int y){
        this.y = y;
    }

    public void run() {
        while(!hungry) {
            move(); 

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }   
    }
}

I have created this class to move a frog object randomly but when I call the move method nothing is happening. I want the frog on a JPanel to randomly move around the screen. I have another class which uses the frog object.

It is used from a main class containing the following:

public void actionPerformed(ActionEvent event) {
    if (event.getSource() == MakePet) {
        String petName = namePlace.getText();
        frog = new Frog(petName,false);
        panel.add(pet);
        panel.add(prey);
        frog.move();
        Thread fro = new Thread(frog);
        fro.start();
    }
}

public static void main(String[] args) {
    GUI demo = new GUI();
    demo.setSize(520,720);
    demo.createGUI();
    demo.show();
}
Sardtok
  • 449
  • 7
  • 18
coderrrrrr
  • 17
  • 4
  • I can't see where the frog is actually drawn. The move() function changes the x and y vars, but these are only used to draw an oval. – Steve Smith Feb 21 '17 at 15:25
  • Could you post the GUI code, or at least relevant snippets? Especially where is display being called from? Also, did you mean to use `dy` for the height of the oval? – Sardtok Feb 21 '17 at 15:28
  • Seems like a duplicate of [this question](http://stackoverflow.com/questions/28928256/randomly-moving-images-on-a-jpanel?rq=1) – Jérôme Feb 21 '17 at 15:28
  • public void actionPerformed(ActionEvent event) { if (event.getSource() == MakePet) { String petName = namePlace.getText(); frog = new Frog(petName,false); panel.add(pet); panel.add(prey); frog.move(); Thread fro = new Thread(frog); fro.start(); }} public static void main(String[] args) { GUI demo = new GUI(); demo.setSize(520,720); demo.createGUI(); demo.show(); ;} – coderrrrrr Feb 21 '17 at 15:29
  • 1
    Don't post code in a comment. Update your question with the code. Actually make sure you post a proper [mcve] that demonstrates the problem. We can't guess what you are doing. You still haven't answered the question on where the frog is drawn. I don't see where the display(...) method is invoked. – camickr Feb 21 '17 at 15:46
  • @coderrrrrr The panel is not being redrawn upon the events occurring, you need to call repaint, and if you make changes to the GUI components contained in the JPanel (i.e. add or remove a component), you may need to call revalidate first. Also, if you're going to have a loop like that, I would move it outside Frog so you can also update other parts. – Sardtok Feb 22 '17 at 10:59
  • I'm not sure what you fully mean Sardtok? – coderrrrrr Feb 22 '17 at 11:28
  • I added an answer based on Jérôme's comment and my own. If you add for instance a JButton to a JPanel, you may have to invalidate it, so it properly updates the component tree, i.e. runs through all components in the JPanel and draws them all. – Sardtok Feb 22 '17 at 11:38

1 Answers1

1

For an example of timer based animation, have a look at http://www.java2s.com/Code/Java/2D-Graphics-GUI/Timerbasedanimation.htm

Another example of timer based animation, where Swing components are used to draw images on a JPanel was given Jérôme's comment: Randomly moving images on a JPanel

If you require having multiple frogs with their own threads of control, then you will need to handle synchronization. Otherwise I would simply call move from the timer before repainting the panel. And then change move:

public void move() {
    if (!hungry) {
        return;
    }
    ...
}

Set the timer's interval appropriately based on the framerate you are looking to achieve. The below is based on the answer from the question Jérôme linked to:

Timer t = new Timer(1000 / DESIRED_FRAMERATE, (event) -> {
    frogs.forEach(Frog::move);
    panel.repaint();
});

Note that this is Java 8 using lambdas.

The above in pre-Java 8:

Timer t = new Timer(1000 / DESIRED_FRAMERATE, new ActionListener() {
    public void actionPerformed(ActionEvent event) {
        for (Frog frog : frogs) {
            frog.move();
        }
        panel.repaint();
    }
});

You should create the Timer in the initialization code of your JFrame or JPanel. If you have a class extending JPanel, you don't need to reference panel when calling repaint if the Timer is inside that class. Also, here I am guessing you have a collection of Frog objects, typically a list, called frogs. If there's only ever one frog, you don't need the loop. Frog's display method needs to be called from the JPanel's paint method, so I am guessing you have a class extending JPanel.

Community
  • 1
  • 1
Sardtok
  • 449
  • 7
  • 18