Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change image in JPanel without using a new JFrame (Repaint() doesn't work! )

I've been working on a drinking game program for school.

//this is the game //http://sotallytober.com/games/verbal/mexican/

Anyway, I painted a image in an JPanel using the following code (it's an class that extends JPanel)

public class iconPanel extends JPanel {

ImageIcon image;
Image pic;
public iconPanel(String startScreenImage) {
      image = new ImageIcon(startScreenImage);
      pic = image.getImage();
      this.setBackground(new Color(0, true));
}

@Override

public void paintComponent(Graphics g) {
    //Paint background first
    g.drawImage (pic, 0, 0, getWidth (), getHeight (), this);
}

Now in my other class, where I have the layout and all the components I declare on top my JPanels like this :

private JPanel pnDrinkPlayerBW;

Then in a method in the same class named MakeComponents I set the JPanel to :

pnDrinkPlayerBW = new iconPanel("img/glass.jpg");
pnDrinkPlayerBW.setPreferredSize(new Dimension(183,61));

Afterwards I add it to the Panel where it has to come, and that panel onto the frame in the method makeLayout() (I don't think that it's useful code, so if you want to see it, ask me)

Then if a button gets pressed, I want to change the glass.jpg image to another image, for example beerGlass0.png, so in the actionlistener in another method actionEvents() I do this:

pnDrinkPlayerBW = new iconPanel("img/beerGlass.png");
pnDrinkPlayerBW.setPreferredSize(new Dimension(183,61));
pnDrinkPlayerBW.repaint();

I'll put the constructor of this class also here, just if people need it :

public SpelScreen(){
    makeComponents();
    makeLayout();
    actionEvents();
} // note : this is'nt the full constructor, just the call for the methods I talked          about, SpelScreen extends JFrame..

So what I want to do, is to set in the class SpelScreen a new image for the iconPanel and repaint it using the same instance of the spelscreen.

I am quite new to Java, so don't expect me to rapidly understand complicated code :)

Thanks!

like image 483
Sytham Avatar asked Feb 13 '23 14:02

Sytham


1 Answers

First off you're forgetting to call super.paintComponent in your paintComponent method. Also paintComponent should be protected not public

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(..);
} 

Second, I don't think you want to create a new iconPanel and immediately call repaint on it. That will probably do nothing.

Instead have a setter for your pic, then just repaint(); inside that method.

public void setPic(Image pic) {
    this.pic = pic;
    repaint();
}

Then you can just call the setPic from the the class you created the iconPanel in. For example

iconPanel panel = new iconPanel("...");
... // then in some listener
public void actionPerformed(ActionEvent e) {
    Image pic = null;
    try {
        pic = ImageIO.read(...);
        panel.setPic(pic);
    } catch ...
}

Another option is just to have an array of images you initialize in the iconPanel. Then in a a listener, you can just change the index the if the image array then call repaint. Something like this

Image[] images = new Image[5];
int imageIndex = 0;
// fill the array with images

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(images[imageIndex], ...);
}

Then you could just change the imageIndex and repaint()


Side Note

You should be using Java naming convention. Class names being with capital letters i.e. iconPanelIconPanel


Update

Using ImageIcon

public void setImage(ImageIcon img) {
    pic = img.getImage();
    repaint();
}
like image 71
Paul Samsotha Avatar answered Feb 16 '23 04:02

Paul Samsotha