Java - Can't get JFrame to refresh image

I've programmed a small text adventure (console) for learning purposes. Now I want to spice it up with some images, but I can't get the images to refresh. What am I doing wrong? Can somebody help me pls?

The main class is GameMaster.java and the class I use to show the picture is DrawRoom.java

The relevant code:


GameMaster.java
class GameMaster
{   

public static void main(String args[])
{

    // Doing some stuff here, like building rooms, etc...

    // Here I start using images
    DrawRoom drawRoom = new DrawRoom();
    Thread myThread = new Thread(drawRoom); 
    myThread.start(); // The first image appears as expected.

    // Then in a while loop, I get user input from the console and process it.
    // According to which room the user is in, I want to draw the corresponding
    //image.

    drawRoom.changeImage("Images/SOME-OTHER-IMAGE.JPG");
    // This however, does not change the shown image!   
}
}

DrawRoom.java
public class DrawRoom extends JPanel implements Runnable{

Image image;
JFrame frame;

    public DrawRoom(){

        this.image = Toolkit.getDefaultToolkit().getImage("Images/GAME-START.JPG"); 
        this.frame = new JFrame("The Current Image");
        this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.frame.setSize(640,510);
    }

    public void paintComponent(Graphics g){

        g.drawImage(image,0,0,640,480, this);
    }

    public static void main(String arg[]){
        // Left empty.
    }

    public void run(){

        DrawRoom panel = new DrawRoom();
        this.frame.setContentPane(panel);
        this.frame.setVisible(true);
    }

    public void changeImage(String whichImage){

        this.image = Toolkit.getDefaultToolkit().getImage(whichImage);
        this.frame.revalidate();
        this.frame.repaint();
    }
}

I'm a newbie, especially new to graphics and threads. Help would be greatly appreciated!

Answers


I suggest you start with source that looks like the following.

What this does is to have the main thread create the displayed frame and panel for the image and to then cycle through changing the images. In this example I have just two images that swap back and forth.

Also make sure your images are in the right folders when testing this and that your path to the image files is correct. If you see nothing but a blank frame, the files not in the right place was the problem for me.

I am not using multiple threads however here is a resource for Constructing Threads and Runnables.

The main class looks like the following:

import javax.swing.*;

public class SimpleThreeTierMain {
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        // Doing some stuff here, like building rooms, etc...

        // Here I start using images
        DrawRoom drawRoom = new DrawRoom();
        JFrame  frame;

        frame = new JFrame("The Current Image");
        frame.setContentPane(drawRoom);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(640,510);
        frame.setVisible(true);

        // Then in a while loop, I get user input from the console and process it.
        // According to which room the user is in, I want to draw the corresponding
        //image.

         long  lTime = 2050;
        int   iChange = 0;
        try {
            while (true) {
                Thread.sleep (lTime);
                if (iChange == 1)
                    drawRoom.changeImage("0112091252a.jpg");
                else
                    drawRoom.changeImage("0112091251.jpg");
                iChange = 1 - iChange;
            }
        } catch (InterruptedException iex) {}
    }
}

The drawing room class looks like the following:

import javax.swing.*;
import java.awt.*;

public class DrawRoom extends JPanel {

    Image image;

        public DrawRoom() {
            this.image = Toolkit.getDefaultToolkit().getImage("0112091251.jpg"); 
        }

        public void paintComponent(Graphics g){
            g.drawImage(image,0,0,640,480, this);
        }

        public void changeImage(String whichImage){
            this.image = Toolkit.getDefaultToolkit().getImage(whichImage);
            this.repaint();
        }
    }

You need to call the repaint() method of the DrawRoom itself:

public void changeImage(String whichImage){

    this.image = Toolkit.getDefaultToolkit().getImage(whichImage);
    this.repaint(); // not this.frame.repaint()!

}

By the way, use a good ol' System.out.println(whichImage) inside the changeImage method to check if it is properly called by your code.

EDIT: you built a new DrawRoom inside run() method, then added it to frame's contentPane - don't do that! Just add the panel to the frame into panel's constructor:

public DrawRoom(){

    this.image = Toolkit.getDefaultToolkit().getImage("Images/GAME-START.JPG"); 
    this.frame = new JFrame("The Current Image");
    this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.frame.setSize(640,510);

    this.frame.setContentPane(this);
    this.frame.setVisible(true);

}

...

public void run(){

    // do not need to create any DrawRoom instances!

}

public void changeImage(String whichImage){

    this.image = Toolkit.getDefaultToolkit().getImage(whichImage);
    this.repaint();

}

Hope it's all now.


Need Your Help

Making a list sortable in ASP.NET MVC using jquery

jquery asp.net-mvc asp.net-mvc-3 razor sortable

I'm trying to figure out how to implement jquery sortable..

What's the easiest way to return a token from a controller action while carrying on a long-running process?

asp.net-mvc multithreading queue

I've got this long-running process in an asp.net MVC3 controller that's functioning as a RESTful service. What I'd like to do is generate a token the caller can use to check on the status of this

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.