Archived

This topic is now archived and is closed to further replies.

RobAU78

[java] Buffered Images

Recommended Posts

Hey everyone, I''ve been learning about BufferedImages, but I''m having trouble fitting everything together. Basically, I want to load a BufferedImage containing an image file onto a JPanel. What''s the easiest way to do this? What''s the best way (if the easiest way isn''t the best)? Thanks, Rob

Share this post


Link to post
Share on other sites
An annoyance in AWT is that images are not considered components, so they cannot assert any size requirements on their surroundings. If you add an image to a JPanel, the image''s size is not taken into consideration when considering how big the JPanel should be, so the image can easily get cut off.

The solution to this problem really depends on the situation, but this is one way...


public class ImagePanel extends JPanel {
private BufferedImage image;
private Dimension dim;

public ImagePanel(String imageFile) {
try {
URL u = getClass().getClassLoader().getResource(imageFile);
image = ImageIO.read(u);
} catch(IOException ioe) {
// failed to load image

}

dim = new Dimension();
}

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

g.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
}

/*
* insist this panel always be at least as big as the image
*/


public Dimension getPreferredSize() {
dim.width = image.getWidth();
dim.height = image.getHeight();

return dim;
}

public Dimension getMinimumSize() {
dim.width = image.getWidth();
dim.height = image.getHeight();

return dim;
}
}


There are issues with this approach, but it works most of the time.

Share this post


Link to post
Share on other sites
The image you are loading needs to have transparency, like gifs or pngs. Otherwise you have to create the transparency yourself, which is a lot more involved.



First make it work,
then make it fast.

--Brian Kernighan

The problems of this world cannot possibly be solved by skeptics or cynics whose horizons are limited by the obvious realities. We need men and women who can dream of things that never were. - John Fitzgerald Kennedy(35th US President)

Do not interrupt your enemy when he is making a mistake. - Napolean Bonaparte

Share this post


Link to post
Share on other sites
The image will be transparent, but the JPanel won''t. At least not in my experience, I''ve not tried making components transparent that much. Taking that ImagePanel class and having it call setOpaque(false) doesn''t appear to do anything.

If you need transparency and you''ve got a lot of images, then the most reliable way would probably be to add them all to the same panel. Then for mouse clicks, the panel would have to accept the mouse event and then figure out which image it should go to.

Share this post


Link to post
Share on other sites
Once you go beyond simply displaying one image, things get more complicated. One approach, is the JPanel becomes more like a context in which things in your app can request to be drawn onto, so you end up with more like a rendering system.


interface Sprite {
public void draw(Graphics g);
}


class ImagePanel extends JPanel {
private List sprites;

public ImagePanel() {
sprites = new ArrayList();

// probably also want to ensure size with the Dimension deal again

}

public void addSprite(Sprite sprite) {
sprites.add(sprite);
}

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

// let each sprite draw themselves onto the panel

for(int i = 0; i < sprites.size(); ++i) {
Sprite s = (Sprite)sprites.get(i);
s.draw(g);
}
}
}


And of course sprites get drawn in the order they are added to the list, so you''d probably want something like addSprite(Sprite sprite, int index).

This is basically how I''ve done all my games, it works well for me.

If you''re headed in this direction, and don''t mind (or even want) a fullscreen game, then look into the fullscreen api. As the above code would slide right into the fullscreen api, all you need is a little bit of initialization (and replace the JPanel with probably a Frame or Canvas). Fullscreen mode gives you a very noticable performance boost on Windows, is apparently better in MacOSX (never tried it myself), and is not yet implemented in Linux (but that is easily worked around).

Share this post


Link to post
Share on other sites
Hmm. How would I load the image files? Or would I do it the same way as before?

This is all for my star map, by the way. I got it to work with creating an ImagePanel for each Star, but now I want to have each Star''s image loaded into the same Panel (or Canvas, or whatever) so that they''ll transparently overlap each other.

I am interested in using the Fullscreen API. However, the star map would not take up the entire screen (just a little under 3/4s of it, with the setup I have right now). Would it be wise then to make a Canvas for the entire game and then add a Panel to it for the star map?

- Rob

Share this post


Link to post
Share on other sites