I am trying to load an image and set to background, but i get the error at selectionPanel method "Could not load background image".
It seems that something is going wrong with the image processing but i cant find out what.
public class selectionPanel extends JPanel
{
//Variable with the name of our pic
private static final String path = "selbkgrnd.jpg";
private ImageIcon imageIcon;
private Dimension windowSize;
private int imageHeight;
private int imageWidth;
protected selectionPanel()
{
this.imageIcon = new ImageIcon("selbkgrnd.jpg"); //Save image to imageIcon
Image image = this.imageIcon.getImage();
this.imageWidth = image.getWidth(null);
this.imageHeight = image.getHeight(null);
if ((this.imageWidth == -1) || (this.imageHeight == -1)) //Check if background image is succesfully loaded
{
JOptionPane.showMessageDialog(JOptionPane.getDesktopPaneForComponent(this), "Could not load background image", "Fatal error!", 0);
System.exit(-1);
}
this.windowSize = new Dimension(this.imageWidth, this.imageHeight);
}
protected void startScreen()
{
setOpaque(false);
setSize(this.windowSize);
}
protected int getImageHeight()
{
return imageHeight;
}
protected int getImageWidth()
{
return imageWidth;
}
#Override
public void paintComponent(Graphics g)
{
g.drawImage(this.imageIcon.getImage(), 0, 0, null);
super.paintComponent(g);
}
}
Usually this is due to your looking in the wrong location for your Image File. Try using the complete path to the image, either that or a path relative to the user's directory which can be found with:
System.out.println("user directory: " + System.getProperty("user.dir"));
Edit
You state:
Thank you it worked with the full path, but isnt it supposed to work with just the image name if it is inside the source code folder ?
No. Again, Java will look for the file relative to the user directory.
Note however that if the image is in the class file directory or in a directory relative to this and you make a jar file out of this and need to access the images, then you can't use files. You will need to get the images as a resource and the relative path will be different since it won't be related to the user.dir but rather will be relative to the location of the class files.
Related
I use eclipse on linux Ubuntu and I have this code for loading image and setting it as background in one of my JPanels:
public class MenuState extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
private GameStateManager gsm;
private int width;
private int height;
public MenuState(GameStateManager gsm)
{
this.gsm = gsm;
width = gsm.getWidth();
height = gsm.getHeight();
SizeManager sm = new SizeManager();
this.setLayout(new BorderLayout());
sm.set_size(this, width, height);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
BufferedImage background_image;
try {
background_image = ImageIO.read(new File("src/res/img/menu_background.png"));
g.drawImage(background_image, 0, 0, width, height, null);
} catch (IOException e) {
e.printStackTrace();
}
}
public void actionPerformed(ActionEvent e) {
}
and it works only in eclipse. When I export it to jar file or runnable jar file program does not show images. I also tried to use
this.getClass().getResource()
and similar codes but it does not work in eclipse. But I am maybe doing something wrong.
I also have this code in another class to play audio:
public class AudioManager {
private Clip clip;
public void play(String audio_name, boolean repeat)
{
try {
File audioFile = new File(audio_name);
AudioInputStream audioStream = AudioSystem.getAudioInputStream(audioFile);
AudioFormat format = audioStream.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, format);
clip = (Clip) AudioSystem.getLine(info);
clip.open(audioStream);
if(repeat)
{
clip.loop(clip.LOOP_CONTINUOUSLY);
}
clip.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void stop()
{
clip.stop();
}
and it plays audio in eclipse but not after I export project.
I suppose File works only for files on disk and not for files in jar file but it is only way I made it works in eclipse.
So, what should I do?
And additional problem:
Sound played in eclipse is lagging, I improved it increasing available memory for eclipse but little lags occur when loading program and changing JPanels in JFrame by clicking on JButtons.
Thanks for any advice.
What String do you put into the getResource method ?
When you use getResource or getResourceAsStream, you must specify the package path. If your file is in the package "com.test.example", then you must put getResource("/com/test/example/my_file.png").
So, with your background image, you must load your image with :
background_image = ImageIO.read(this.getClass().getResource("/res/img/menu_background.png"));
You should do the same way with your audio file.
I also recommend you to load your image outside of the paintComponent method. Otherwise, each time your panel is repainted, the image is reloaded.
I am trying to scale an image to fit the screen width.
Therefore I am trying to load the imported multi image in the beforeTerminalGUI method here:
#Override
protected void beforeTerminalGUI(Form f) {
ImageViewer iv = findImageViewer(f);
Image i = fetchResourceFile().getImage("stillstand.PNG");
i.scaledWidth(iv.getWidth());
iv.setImage(i);
}
which was created when I clicked the beforeShow event in the gui builder. (I also saved the GUI builder after doing so)
But I am getting this error:
java.lang.ArithmeticException: / by zero
at com.codename1.impl.javase.JavaSEPort.scaleArray(JavaSEPort.java:3505)
at com.codename1.impl.javase.JavaSEPort.scale(JavaSEPort.java:3497)
at com.codename1.ui.Image.scale(Image.java:961)
at com.codename1.ui.Image.scaledImpl(Image.java:931)
at com.codename1.ui.Image.scaled(Image.java:896)
at com.codename1.ui.Image.scaledWidth(Image.java:835)
at com.codename1.ui.EncodedImage.scaledWidth(EncodedImage.java:536)
at userclasses.StateMachine.beforeTerminalGUI(StateMachine.java:37)
at generated.StateMachineBase.beforeShow(StateMachineBase.java:537)
at com.codename1.ui.util.UIBuilder.showForm(UIBuilder.java:2512)
at com.codename1.ui.util.UIBuilder.showContainerImpl(UIBuilder.java:2334)
at com.codename1.ui.util.UIBuilder.showContainer(UIBuilder.java:2214)
at com.codename1.ui.util.UIBuilder$FormListener.actionPerformed(UIBuilder.java:2900)
at com.codename1.ui.util.EventDispatcher.fireActionEvent(EventDispatcher.java:338)
at com.codename1.ui.Form.actionCommandImpl(Form.java:1415)
at com.codename1.ui.Form.dispatchCommand(Form.java:1381)
at com.codename1.ui.SideMenuBar$CommandWrapper$ShowWaiter.run(SideMenuBar.java:1611)
at com.codename1.ui.Display.processSerialCalls(Display.java:1147)
at com.codename1.ui.Display.edtLoopImpl(Display.java:1091)
at com.codename1.ui.Display.mainEDTLoop(Display.java:994)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)
same happens for the methods i.scale (..),i.scaledHeight(..) whenever I run the app and want to switch to the TerminalGUI.
I am new to CodenameOne and any help is welcome.
The problem is iv.getWidth() You should use iv.getImage().getWidth(), this will return the width of the ImageViewer's image and not the width of the component itself. Also check for existence of the image stillstand.PNG before scaling it.
#Override
protected void beforeTerminalGUI(Form f) {
ImageViewer iv = findImageViewer(f);
Image i = Resources.openLayered("/theme").getImage("stillstand.PNG");
if (i != null) {
i.scaledWidth(iv.getImage().getWidth());
iv.setImage(i);
} else {
System.out.println("Image not found");
}
}
Another way to scale the image to fit the screen width is doing this:
#Override
protected void beforeTerminalGUI(Form f) {
ImageViewer iv = findImageViewer(f);
Image i = Resources.openLayered("/theme").getImage("stillstand.PNG");
if (i != null) {
iv.setImage(i.scaledWidth(Display.getInstance().getDisplayWidth()));
} else {
System.out.println("Image not found");
}
}
I am having trouble setting images in my newest game. When I call the method getImage(String), and I get the Image like so:
Image head = getImage("Torso_model_01.png");
I get the following error message:
Err: java.lang.NullPointerException
At PB2Main.Body(Body.java : 27)
...
and so on...
On this tutorial, it explains how to get an image using ImageIcon like so:
String imgFile = "Images/" + img;
URL imgURL = getClass().getClassLoader().getResource(imgFile);
ImageIcon imageIcon;
Image image;
if(imgURL != null){
imageIcon = new imageIcon(imgURL);
image = imageIcon.getImage();
}
final Image anImage = image;
I made a method for this:
public URL getURL(String img){
String imgFile = "Images/" + img;
URL imgURL = getClass().getClassLoader().getResource(imgFile);
return imgURL;
}
Then I made a method called getImage(String)
public Image getImage(String img) {
ImageIcon imageIcon;
Image image;
URL imgURL = getClass().getClassLoader().getResource(getURL(img));
if(imgURL != null){
imageIcon = new ImageIcon(imgURL);
image = imageIcon.getImage();
return image;
}
System.err.println("Unable to Locate Image: " + imgURL);
}
Now, I have a class called Body.
In that class, I have a constructor:
public Body(float x, float y, String head, String torso){//atm this is just so i can get the image to actually draw on the screen
Image Head = debugger.getImage(head);// debugger doubles as a library and debugger
//i also can't have this class extend debugger otherwise it will create a window :/
// is that a glitch or something in Java? :L perhaps i just don't understand
// inheritance very well and what happens exactly when you inherit a class :(
Image Torso = debugger.getImage(torso);
g2.drawImage(Head, canvas.geWidth()/ 2,canvas.getHeight()/2, null)// canvas: the window to
//draw to
// can someone also quickly explain in their answer what an image observer is please?
g2.drawImage(Torso, Head.getX() - 5, Head.getY() - 5, null);
}
The compiler gives me the following error message:
java.lang.NullPointerException
At PlazmaBurst2.Body(Body.java: 37)
//the code it brings me to is line 1 in the constructor:
/* null: */ Image Head = debugger.getImage(img);
I don't understand where this NullPointerException is coming from. I did it exactly how they do it in the Custom Graphics Programming section of the same site.
The code works fine if I just copy and paste the code, but not if I use the method getImage(String).
You're problem is on line 3 of getImage(String):
URL imgURL = getClass().getClassLoader().getResource(getURL(img));
This should be changed to:
URL imgURL = getURL(img);
I am using Jtree for listing various images of a directory, I want to display image on applet when the user click on the image name displayed in the Tree, the code i'm using is as below, ta is an object of the applet because i'm using it in another class.
private void displayImage(URL furl, String fname) {
ta.Picture = ta.getImage(furl, fname);
prepareImage(ta.Picture, this);
Graphics g = ta.imageCanvas.getGraphics();
g.clearRect(10, 10, 800, 800);
g.drawImage(ta.Picture, 10, 10, this);
} // displayImage
public void valueChanged(TreeSelectionEvent e)
{
// TODO Auto-generated method stub
FileTreeNode node = (FileTreeNode) tree.getLastSelectedPathComponent();
System.out.println("slecte asldf " + node.isLeaf());
if (node.isLeaf())
{
currentFile = node.file;
System.out.println("File name " + currentFile.getName());
try
{
URL furl = new URL("file:/F:/photos");
displayImage(furl, currentFile.getName());
}
catch (MalformedURLException mle)
{
System.out.println("Exception::::::" + mle);
}
}
else
currentFile = null;
}
But its not working.
As you are showing files from the local filesystem, working with URLs is not required. Use
displayImage(currentFile);
and rewrite that method as following:
private void displayImage(File file) {
BufferedImage image = ImageIO.read(file);
ta.image = image;
ta.repaint();
}
where the paint method of the (I an assuming) component ta must be like
BufferedImage image;
public void paint(Graphics g) {
g.clearRect(10, 10, 800, 800);
g.drawImage(ta.Picture, 10, 10, this);
}
Because of security reasons, the applet will only be able to access the file system if signed or running without security manager (most often on the same computer).
But its not working.
This is in no way helpful, do you get exceptions? What happens? Please post an SSCCE for better help sooner
I want to display image on applet when the user click on the image
name displayed in the Tree, the code i'm using is as below, ta is an
object of the applet because i'm using it in another class.
IMO you are going about it wrong using the JPanel object and Component#getGraphics.
Dont use Component#getGraphics() as its not good practice and not persistent thus on next call to repaint() the screen will be cleared.
Dont use Applet with Swing components rather use JApplet.
Add a custom JPanel with getters and setters for BufferedImage variable to the container and than override paintComponnet and draw the BufferedImage there.
Now to change the BufferedImage simply call the setter i.e setBackgroundImage(BufferedImage img) and than call repaint() on JPanel to show the changes. Like so:
public class MyPanel extends JPanel {
private BufferedImage bg;
public MyPanel(BufferedImage bi) {
bg=bi;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d=(Graphics2D)g;
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
g2d.drawImage(bg,0,0,this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(bg.getWidth(),bg.getHeight());
}
public BufferedImage setBackgroundImage(BufferedImage bi) {
bg=bi;
}
}
Now we use it like so:
MyPanel mp=new MyPanel(...);//create the panel with an image
...
add(mp);//add to container
...
mp.setBackgroundImage(..);//change the image being displayed
mp.repaint();//so the new image may be painted
When I tried to to create an image I was using this line but got no images, just blank lines.
g.drawImage(getImage(getDocumentBase(), "Piece_1.png"),coorx,
coory, SIZE_Y / 8, SIZE_Y / 8, this);
How do you display an image and where do you put it in an eclipse project?
Eclipse IDE executes the programs from the src directory. These steps solved me this problem.
Create a new package called resources. You can name it whatever you want.
Add your image files into that package.
Now first load your image before drawing it.
public Image getImage(String name){
URL imgUrl = getClass().getClassLoader().getResource("resources/"+name);
ImageIcon icon = new ImageIcon(imgUrl);
return icon.getImage();
}
An Example
The constructor you can have.
Image piece1;
public Checkers(){
piece1 = getImage("Piece_1.png");
}
public void paint(Graphics g){
if (piece1!=null){
g.drawImage(piece1, xcoord, ycoord, null);
}
}
Hope this solves your problem.