1

I wanted to create a JFrame and put a sequence of images for animation in there. But the images don't appear in the frame window. I just want basic troubleshooting tips to make it appear in the window. Just edit the code for an answer if you can.

My question: Why isn't the window displaying any pictures? It shows a window with a background color of blue, but that's it. Please tell me an efficient way to store images in variables and display it in a loop.

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.imageio.ImageIO;
import javax.swing.*;

import java.io.*;



public class Game extends JLabel implements ActionListener{


 /**
  * 
  */
 private static final long serialVersionUID = 1L;
 public static Game blah;
  BufferedImage nekopics[] = new BufferedImage[7];

 BufferedImage currentimg;
 public String nekosrcs[];
 int xpos;

 Timer timer;

 public Game() throws IOException
 {
      JFrame jframe = new JFrame();




      nekosrcs = new String[] { "walk1.png", "walk2.png",

              "walk3.png", "walk4.png", "walk5.png",

              "walk6.png"};

    jframe.setTitle("Game");
    jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jframe.setLayout(new FlowLayout());

    jframe.setSize(400, 400);
    jframe.setResizable(false);
    jframe.setVisible(true);

    jframe.getContentPane().setBackground(Color.BLUE);




     for (int i=0; i < nekopics.length; i++) {

 nekopics[i] = ImageIO.read(new FileInputStream("D:/Programs 
                                              /pics"+nekosrcs[i]));

     }

     for (int i=0; i < nekopics.length; i++) {
         timer = new Timer(1000, this);
            timer.setInitialDelay(0);
            timer.start();
         currentimg = nekopics[i];

         repaint();


     }



 }

public void paintComponent(Graphics g)
{
    super.paint(g);

    g.drawImage(currentimg,100,100,this);
}



 public static void main(String[] args) throws IOException {

blah = new Game();



}

public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub

}




}
  • 2
    You can see a running example of the Swing [Timer](https://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html) class [here](http://stackoverflow.com/questions/34746795/creating-an-animated-4x4-grid-in-java/34748083#34748083) – Frakcool Aug 16 '16 at 03:04
  • 2
    *My questions:* Please ask one question per post, as you said, you're new here, so please go through the [help] and learn [ask] and how to make a [mcve] as well as how to indent your code correctly please, I already indented it, but I should be doing that, next time do it correctly before posting it, also please follow the [Java naming conventions](http://www.oracle.com/technetwork/java/codeconventions-135099.html): *"Variable names should start with a lower case"* – Frakcool Aug 16 '16 at 03:14
  • 1
    Also why are you extending `JFrame` and creating a `JFrame` object? Do one or the other, I recommend the latter, because if you extend a `JFrame` you're saying that your class is actually a `JFrame`, instead if you need to extend something, extend `JPanel` so you can later add those panels to another `JFrame` – Frakcool Aug 16 '16 at 03:18
  • Thanks for the feedback, but the images still do not appear in the window. I have performed the edits you proposed. Would love it if you could check if I used the timer properly in this new code. – noobprogrammer Aug 16 '16 at 12:43

1 Answers1

2

Alright, there are a lot of problems in your code, let's step into each of them:

  1. You have a lot of spaces between lines, that makes your code a lot larger and harder to read

  2. You haven't indented your code correctly (see the last } on your code, it's at the same level than the others; your for loops, etc), it makes the code so much harder to read and understand as well

  3. You're creating a JFrame but extending JLabel, I'm not sure why you're doing this, if you're doing it so you can use the paintComponent() method, it's not necessary, on my code you can see how you can do it w/o extending any Component

  4. If you haven't read the Swing Timer docs you should click that link and read what the ActionListener parameter does. In this case, we're going to use this listener to call the repaint() method and update our currentImage (or nextImage in the code below) and change the image accordingly. You failed to do this.

  5. You were creating more than 1 Timer too, you created 6 here! All of them new but they had no action to do when the time finished

    for (int i=0; i < nekopics.length; i++) {
        timer = new Timer(1000, this);
        timer.setInitialDelay(0);
        timer.start();
        currentimg = nekopics[i];
        repaint();
    }
    
  6. You're changing unnecessarily the visibility of the paintComponent() method to public from protected


However I want to congratulate you for not using a null layout and following the recommendations I made on the comments above.


And finally the code that changes one image for another inside a Timer is the following, you can copy-paste it and change the image's names so you can see how it works.

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class ImageSequence {
    private JFrame frame;
    private JPanel pane;
    private Timer timer;
    private int nextImage = 0;
    private String[] images = {"tokyo", "tokyo2", "starwars"};
    private Image img = null;
    public static void main (String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ImageSequence().createAndShowGui();
            }
        });
    }

    public void createAndShowGui() {
        frame = new JFrame("Image Sequence");
        timer = new Timer(1000, listener);
        pane = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                try {
                    img = ImageIO.read(new FileInputStream("/home/jesus/Pictures/" + images[nextImage] + ".jpg"));
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                g.drawImage(img , 0, 0, 200, 200, this);
            }

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
        };

        timer.start();

        frame.getContentPane().add(pane);
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    ActionListener listener = new ActionListener() {   
        @Override
        public void actionPerformed(ActionEvent event) {
            System.out.println(nextImage);
            nextImage = nextImage < images.length - 1 ? nextImage + 1 : 0;
            System.out.println(nextImage);
            pane.repaint();
        }
    };
}
Frakcool
  • 10,915
  • 9
  • 50
  • 89
  • Thanks, it worked like a charm! Although there are a bunch of new methods I would have to look up for now. Gosh..I am really an amateur! I will act on your suggestions and for the next time I post here, would make my codes alot more cleaner and readable. Thanks for the help! – noobprogrammer Aug 17 '16 at 01:32
  • @noobprogrammer No problem, try using an IDE they will suggest you the methods you want, I'm not the best but I have studied swing by 4 years now (everything while reading SO Q&A), I'm actually a beginner too compared with some other users, I'm glad you want to improve your posts and your programming skills too, so, good luck and happy programming :) – Frakcool Aug 17 '16 at 05:45