4

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!

Sytham
  • 824
  • 3
  • 11
  • 25
  • You're forgetting to call `super.paintComponent` in your `paintComponent` method. – Paul Samsotha Mar 05 '14 at 10:03
  • 1
    You mean like this? public void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage (pic, 0, 0, getWidth (), getHeight (), this); – Sytham Mar 05 '14 at 10:06

1 Answers1

8

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();
}
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • many thanks! but still got few problems.. first of all the ImageIO.read(URL) doesn't work, so I used ImageIcon image = new ImageIcon(URL); but then the Panel.setImage(image) gives an error "the method is undefined" I'm sorry, probaly easy things to fix.. – Sytham Mar 05 '14 at 10:24
  • If you want to do that than the `setImage` method should take a `ImageIcon` instead of an `Image` as an argument, and then you need to make the `pic = `image.getImage()` in the method. Do you get it? – Paul Samsotha Mar 05 '14 at 10:26
  • See mt **UPDATE** at the bottom; – Paul Samsotha Mar 05 '14 at 10:28
  • Yes, but I think it can't acces the method from IconPanel.. error : "The method setImage(ImageIcon) is undefined for the type JPanel" (I've set the method of setImage to ImageIcon, and then I made it into an Image, so that's not the problem) – Sytham Mar 05 '14 at 10:33
  • You can't do this `JPanel panel = new iconPanel`. It must be `iconPanel panel = new iconPanel`. When you do the first, you're limited to the method of `JPanel` and not `iconPanel` – Paul Samsotha Mar 05 '14 at 10:34
  • Wow, I feel really stupid! :) thanks a LOT ! great advice! works like a charm now! – Sytham Mar 05 '14 at 10:38
  • Also you may want to consider my second option I posted. It may be more optimal. Creating a new image in the listener every time you press a button for instance, isn't efficient. – Paul Samsotha Mar 05 '14 at 10:38
  • Thanks, I'll do that ! And I need to check my naming convention indeed, thanks! – Sytham Mar 05 '14 at 10:41
  • I stumbled upon another problem, that is that the background of the image I want to paint (background is set transparent with photoshop) is filled up with some other thing, like the border of my frame and other things that are on my JFrame, when I switch the window to antoher program like chrome, and I switch back, it is gone.. – Sytham Mar 05 '14 at 11:49
  • Um not sure i understand the problem, but you can paint a background color by just `g.setColor(Color.GRAY); g.fillRect(0, 0, getWidth(), getHeight());` before you draw your image. Also you `must` call `super.paintComponent` if you already haven't. – Paul Samsotha Mar 05 '14 at 12:01
  • I have an image of a dice, and the background of that image is transparent, so when painted only the dice is visible, but now the background of the dice i just painted has some strange things in it, here's the photo http://imgbin.org/index.php?page=image&id=16995 after I click away it looks like this : http://imgbin.org/index.php?page=image&id=16996 – Sytham Mar 05 '14 at 12:13
  • I see a background and I see the dice. Are they different components or are then drawn on the same panel? Also anywhere you paint, you _must_ call `super.paintComponent`. Did you do that? If you don't it will cause things like in your linked image, which are called paint artifacts. – Paul Samsotha Mar 05 '14 at 12:19
  • You may want to post a new question and post a runnable program replicating the problem, that people can test out. I can only guess without a runnable program. – Paul Samsotha Mar 05 '14 at 12:21
  • Found the solution, just do UpdateUI(); on the main JPanel where everything is put on – Sytham Mar 05 '14 at 13:14