Thursday, 1 September 2016

java - Trouble adding Image to a JPanel



I'm making a video game, and I need to add an image to a JPanel and then add that JPanel to a JFrame. All of the tutorials I've seen say to add it to a JLabel, but the image needs to be able to move around. Unless you can move a JLabel around, I can't do that. How would I be able to add an Image directly to a JPanel. This is what I have so far, but it is just like it was on a JApplet



class Penguin extends JPanel {


public Image image;

public void paintComponent( Graphics g ) {

image = getImage( getDocumentBase(), "Penguins.jpg" );
g.drawImage( image, 0, 0, this );
}
}


Answer



You can easily move a JLabel around, so this is still a viable option, and there are tricks available that can let you do that including using a JLayeredPane, or the glass pane. But having said that, still it is not difficult to paint an image in a JPanel (and I'm betting that your Google search has shown you how to do this). The key is draw it with a Graphics' object's drawImage(...) method in the JPanel's paintComponent(...) method override.



We can likely give you much better and more specific advice if you desire, if you give us more details about your current code and your current problems.



Edit:
Regarding your posted code: first off, do not read in a file within a paintComponent(...) method. This will slow down your GUI's drawing and make your GUI responsiveness terrible. Also, why have your code re-read in the same image file each time a repaint occurs? No, instead read the file in once and save it in the Image variable. Perhaps you should read it in using ImageIO.read(...).



Next, you still need to move the file into the jar file as has been recommended to you previously.



Edit 2:
For example with code like so:




Penguin.java



package myPackage;

import java.awt.Graphics;
import java.awt.Image;
import java.io.IOException;
import java.io.InputStream;


import javax.imageio.ImageIO;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Penguin extends JPanel {
private Image image;

public Penguin(String imageResource) throws IOException {
InputStream inStream = getClass().getResourceAsStream(imageResource);
image = ImageIO.read(inStream);

}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
g.drawImage(image, 0, 0, this);
}
}
}



PenguinApplet.java



package myPackage;

import java.awt.BorderLayout;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;


import javax.swing.*;

@SuppressWarnings("serial")
public class PenguinApplet extends JApplet {
@Override
public void init() {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
createAndShowGui();

}
});
} catch (InterruptedException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}

public void createAndShowGui() {

String penguinImgResource = "images/MyImage.jpg";
try {
Penguin penguinPanel = new Penguin(penguinImgResource );
getContentPane().add(penguinPanel, BorderLayout.CENTER);
} catch (IOException e) {
e.printStackTrace();
}
}
}



You could have the images in the images package, off of the package with the class files:



enter image description here



The key question here is where are the images stored relative to the class files? In my example the class files are held in the myPackage, and the image is in myPackage/images, and so the relative path is simply images. So any images in the image folder would have to be referenced with this path, here "images/MyImage.jpg", and obtained as a resource, not a file.


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...