2

I was trying to build a basic program in java which creates a window with a JPanel,and when user clicks on the JPanel an image is displayed but when run the app and click on the JPanel nothing shows up...

Here goes the code...

//driver.java

import javax.swing.JFrame;

public class driver {

    public static void main(String[] args) {        
        Gui obj = new Gui();
        obj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        obj.setSize(400, 400);
        obj.setVisible(true);   
    }
}

//GUI.java
import javax.swing.*;    
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Gui extends JFrame{    

    public JPanel panel;
    public ImageIcon img;       

    public Gui(){       
        panel = new JPanel();       
        panel.setBackground(Color.DARK_GRAY);       
        img = new ImageIcon("cross.png");
        panel.addMouseListener(new MouseAdapter(){
                public void mouseReleased(MouseEvent e){
                    panel.add(new JLabel(img));
                    System.out.println("Mouse Click detected");
                }}
                );      
        add(panel);
    }       
}

//Updated Gui.java

import javax.swing.*;    
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Gui extends JFrame{

public JPanel panel;
public ImageIcon img;
public final JLabel label;

public Gui(){       
    panel = new JPanel();
    label = new JLabel();
    panel.add(label);   

    img = new ImageIcon(getClass().getResource("res/cross.png"));
    panel.addMouseListener(new MouseAdapter(){
            public void mouseReleased(MouseEvent e){
                label.setIcon(img);
                System.out.println("Mouse Click detected");
            }}
            );
    add(panel);
}   

}

Note: here is how my project is organised

Aditya Bhatnagar
  • 105
  • 1
  • 1
  • 7
  • Is `System.out.println("Mouse Click detected");`this printed? – porfiriopartida Sep 29 '13 at 07:37
  • Have you tried calling revalidate on panel after you add the label...? – MadProgrammer Sep 29 '13 at 08:14
  • @porfiriopartida yes, the string is printed but img is not added (or displayed) in the panel. – Aditya Bhatnagar Sep 29 '13 at 10:09
  • @MadProgrammer I tried using revalidate on JPanel but the image is not displayed on the panel.. – Aditya Bhatnagar Sep 29 '13 at 10:13
  • @AdityaBhatnagar : No the image should be alongside `.class` files, not with `.java` files. Please have a look at this [answer](http://stackoverflow.com/a/11372350/1057230), for the directory structure. Moreover, the advice as suggested in the answer below, is worth noting, since, it is better to just change the icon, instead of placing a new `JLabel`. For detailed information, please see this thread, regarding how to [add Images to the Project](http://stackoverflow.com/a/9866659/1057230) – nIcE cOw Sep 29 '13 at 10:17
  • If you see that print then your file is not where should be. You will have to add the folder with your resources as your classpath or just add the image to your classes. ImageIcon accepts File, you could try new File(img) and then verify if that File exists or print new File("pic.png").getAbsolutePath() so you can know where it should be. – porfiriopartida Sep 29 '13 at 10:21
  • @nIcEcOw i updated my project and shared a link showing how my project is now organised in eclipse.. – Aditya Bhatnagar Sep 29 '13 at 11:43
  • @AdityaBhatnagar : Seems like you forgot to provide previleges to public :-) I hope you had seen this link ([using Eclipse](http://stackoverflow.com/a/9278270/1057230)) from the links already provided :-) – nIcE cOw Sep 29 '13 at 11:45
  • @nIcEcOw sorry, link is now made public :p – Aditya Bhatnagar Sep 29 '13 at 11:56
  • You can access the image with this now `ImageIcon image = new ImageIcon(GUI.class.getResource("/cross.png"))`. THat will do. – nIcE cOw Sep 29 '13 at 12:04
  • @nIcEcOw It worked.. Thanks a ton dude.. :) but can you please tell me how ImageIcon(Gui.class.getResource("/cross.png")) works.. – Aditya Bhatnagar Sep 29 '13 at 12:39
  • @AdityaBhatnagar : Hadn't you seen the link I gave you or __Mr. AndrewThompson__ gave you, they contain this [link](http://stackoverflow.com/a/9866659/1057230), it contains a link referred to as [different ways of loading a resource](http://stackoverflow.com/a/676273/1057230). In simple terms, whatever is inside `Resource` folder, that is accessed not the folder itself. So first forward slash is to refer to the root (or just alongside the base package or if no package is specified then it is where the .class file is). If you will look inside the `bin` folder, – nIcE cOw Sep 29 '13 at 13:00
  • continued... : you will see the cross.png image without the `res` folder. So you are accessing that, via the first forward slash `(getClass().getResource("/cross.png"))`. Hope you understood :-) For the rest You're MOST WELCOME and KEEP SMILING :-) – nIcE cOw Sep 29 '13 at 13:00
  • @nIcEcOw thanks for the explanation,i also followed those links and now this concept is crystal clear to me.. Thank you assistance .. :) – Aditya Bhatnagar Sep 30 '13 at 09:59

1 Answers1

2

Change..

    // ..
    panel.addMouseListener(new MouseAdapter(){
            public void mouseReleased(MouseEvent e){
                panel.add(new JLabel(img));
                System.out.println("Mouse Click detected");
            }}
            );      

To (something like - untested):

    // ..
    final JLabel label = new JLabel();
    panel.add(label);
    panel.addMouseListener(new MouseAdapter(){
            public void mouseReleased(MouseEvent e){
                label.setIcon(img);
                System.out.println("Mouse Click detected");
            }}
            );      

This is the basic technique used in ImageViewer, though it changes image on a Swing Timer, as opposed to mouse click.


Of course, it is easier to do with JButton icons rather than a JLabel/MouseListener. A JButton does not require any listener to change icons, and works for both mouse and keyboard activity. E.G. as seen in this answer.


img = new ImageIcon("cross.png");

By the time of deployment, those resources will likely become an .

That being the case, the resource must be accessed by URL instead of File. See the info page for the tag, for a way to form an URL.

Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • Thanks for explaining with such good examples but even invoking setIcon method on the label object doesn't display the icon on the JPanel... – Aditya Bhatnagar Sep 29 '13 at 10:26
  • Show the new code as an [edit to the question](http://stackoverflow.com/posts/19075584/edit). Please post an [SSCCE](http://sscce.org/). To make an SSCCE of an image example 'SC' (self contained), it will be necessary to do something like generate the image at run-time (a synthetic image as in the 1st SSCCE I linked to) or load the image from an URL at run-time (as the 2nd linked SSCCE does). – Andrew Thompson Sep 29 '13 at 10:56
  • I have posted the updated code and have used URL instead of file this time, now i am getting null pointer exception at line img = new ImageIcon(getClass().getResource("res/cross.png")); – Aditya Bhatnagar Sep 29 '13 at 11:59
  • `new ImageIcon(getClass().getResource("res/cross.png"))` 1) Should best be `new ImageIcon(getClass().getResource("/res/cross.png"))` (with leading `/`). 2) Does it work for synthetic or hot-linked image? If so, this is really a 'where is the resource?' problem. – Andrew Thompson Sep 29 '13 at 12:44