jack
jack

Reputation: 39

How to animate an ImageIcon on a JFrame the image will load but wont change

I'm trying to make a sprite for my game to animate it loads into the JFrame on top of the background but it won't change to the next frame on my animation does anyone know how to solve this? and I'm sorry if it's a simple mistake but I am new to java.

My Main Class

package com.projectelrond.main;

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

import com.projectelrond.Sprites.Ranger;

public class Main extends JFrame{

private static final long serialVersionUID = 1L;

public int WIDTH = 160, HEIGHT = WIDTH/12 *9, SCALE = 3, X = 10, Y = 10;

public boolean running = false;

JFrame f = new JFrame("name");

BackGround bg = new BackGround();
JLabel BackGround = new JLabel(new ImageIcon(bg.Bg));

Ranger R = new Ranger();
JLabel Ranger = new JLabel(R.RangerA[R.I]);

public static void main(String[] args) {
    new Main();

}

public Main() {

    Ranger.setSize(Ranger.getPreferredSize());

    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize(WIDTH * SCALE, HEIGHT * SCALE);
    f.setResizable(false);

    running = true;

    BackGround.add(Ranger);

    f.add(BackGround);
    f.setVisible(true);


    run();
}

public void run() {
    while (running) {
        Render();
    }
}

public void Render() {
    Ranger.repaint();
}

}

And My Ranger Class (I'm trying to get this to animate)

package com.projectelrond.Sprites;

import java.awt.Graphics;
import java.awt.MediaTracker;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.Timer;

public class Ranger extends JLabel implements ActionListener {

private static final long serialVersionUID = 1L;

public int X, Y, I = 0, TotalImages = 2;

public BufferedImage Ranger1, Ranger2;

public ImageIcon RangerA[]; 

private Timer RTimer;

public Ranger() {
    try {
        Ranger1 = ImageIO.read(getClass().getResource("/Images/Sprites/Ranger" + 0 + ".png"));
        Ranger2 = ImageIO.read(getClass().getResource("/Images/Sprites/Ranger" + 1 + ".png"));

    } catch (IOException e) {
        e.printStackTrace();
    }
    Array();
}


public void Array() {
    RangerA = new ImageIcon[TotalImages]; {
        RangerA[0] = new ImageIcon(Ranger1);
        RangerA[1] = new ImageIcon(Ranger2);
    }
    startAnimation();
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (RangerA[I].getImageLoadStatus() == MediaTracker.COMPLETE) {
        RangerA[I].paintIcon(this, g, 0, 0);
        I = (I + 1) % TotalImages;
    }
}

public void startAnimation() {
    if (RTimer == null) {
        I = 0;
        RTimer = new Timer(100, this);
        RTimer.start();
    } else if (!RTimer.isRunning()) {
        RTimer.restart();
    }
}

@Override
public void actionPerformed(ActionEvent e) {
    repaint();
}
}

Upvotes: 0

Views: 373

Answers (1)

camickr
camickr

Reputation: 324207

Variable names should NOT start with an upper case character. Method names should not start with an upper case character. Any text book you use or tutorial you find will follow Java naming conventions. Don't make up your own.

Don't extend JLabel. There is no need to do custom painting. All you want to do is toggle the Icon and let the label paint the Icon itself.

So one way to do this is to create a class for your Timer. When you create the class you can pass in the JLabel and the Array of Icons. Then this class will start the Timer and change the index of the Array and final just invoke label.setIcon(...) with the proper Icon. So basically your Ranger class would just implement the ActionListener of the Timer.

For a slightly different approach you can check out Animated Icon. This solution creates a custom Icon that can toggle the Icons itself. So you just add the Icon to the label.

Upvotes: 2

Related Questions