Java – How to call a function when I click on a jPanel (Java)

componentseventsjavajpanel

I'm working with Netbeans IDE in Java.

I've a form with one JPanel.
Each JPanel has a gridLayout 3×3 and in each place there is an image representing a number[0,1,2,3,4,5,6,7,8](the image is created used a custom class,not just fitting the image in a lab).

I want to be able to exchange two images in the panel when the user click them (First click: no action , second click: switch the two images fitted in the jPanel Components).

I already created a function exchangeComponents and with a test code (like:

exchangeComponents (0,8,jPanel1)

it exchanges correctly the images located in position1 (1st row,1st column) and in position2 (3rd row,3rd column).

The function a creted is the following:

public void exchangeComponents(int component1,int component2,JPanel jpanel){
    try{
   Component aux1 = jpanel.getComponent(component1);
   Point aux1Loc = aux1.getLocation();
   Component aux2 = jpanel.getComponent(component2);
   Point aux2Loc = aux2.getLocation();
   aux1.setLocation(aux2Loc);
   aux2.setLocation(aux1Loc);
   }
   catch (java.lang.ArrayIndexOutOfBoundsException ex){ /* error! bad input to the function*/
       System.exit(1);
   }
}

I suppose I neeed to have an event that call the function exchangeComponents() when the user click on one of the images on the jPanel1 but how should I do it? and how to check what components (images) the user has selected?
I just know that when I create a Button if a click on it (from the IDE) an event like

 private void button1ActionPerformed(java.awt.event.ActionEvent evt) {  
// some code..
}

is created and the code I fill in is executed.

Thank you in advance for any hint.

Best Solution

You need to add the same mouse listener to all you JLabels or whatever container you have for your images, like:

img1.addMouseListener(this);
img2.addMouseListener(this);

etc., then detect which Jlabel you clicked with MouseEvent.getSource(); , like this

boolean hasclicked1=false;
JLabel click1label=null;

public void mouseClicked(MouseEvent me){
  if(!hasclicked1){ //clicked first pic
    hasclicked1 = true;
    click1label = (JLabel) me.getSource();
  } else { //clicked second pic
    hasclicked1 = false;
    exchangeComponents(click1label, (JLabel) me.getSource(), /*your jpanel here*/);
  }
  //now change exchangeComponents so it uses JLabels as parameters
public void exchangeComponents(JLabel component1, JLabel component2, JPanel jpanel){
  try{
    Component aux1 = component1;
    Point aux1Loc = aux1.getLocation();
    Component aux2 = component2;
    Point aux2Loc = aux2.getLocation();
    aux1.setLocation(aux2Loc);
    aux2.setLocation(aux1Loc);
  } catch (java.lang.ArrayIndexOutOfBoundsException ex) { /* error! bad input to the function*/
   System.exit(1);
  }
}

If you are not using JLabels for the images though, replace JLabel in the code with whatever you are using...

EDIT: Sorry, I don't think I made this unclear, but your class with the method exchangeComponents has to implement MouseListener. Then, in the mouseClicked event put the code I gave for it. Make sure to include the variables hasclicked1 and click1label in your class. Make you class something like this

public class ComponentExchanger implements MouseListener {
boolean hasclicked1=false;
JLabel click1label=null;
JPanel mainPanel;
public ComponentExchanger(){
   //create JFrame, JPanel, etc.
   JFrame f=new JFrame();
   //etc.
   mainPanel=new JPanel();
   f.add(mainPanel);
   //set layout of panel, etc.
   for(int i=0;i<9;i++){
      JLabel l=new JLabel(/*label image here*/);
      Point loc=new Point(/*coordinates here*/);
      l.setLocation(loc);
      mainPanel.add(l);
      /*more code*/
      f.setVisible(true);
   }
}

public static void main(String args[]){
   new ComponentExchanger();
}


public void mouseClicked(MouseEvent me){
  if(!hasclicked1){ //clicked first pic
    hasclicked1 = true;
    click1label = (JLabel) me.getSource();
  } else { //clicked second pic
    hasclicked1 = false;
    exchangeComponents(click1label, (JLabel) me.getSource(), mainPanel);
  }
  //now change exchangeComponents so it uses JLabels as parameters
public void exchangeComponents(JLabel component1, JLabel component2, JPanel jpanel){
  try{
    Component aux1 = component1;
    Point aux1Loc = aux1.getLocation();
    Component aux2 = component2;
    Point aux2Loc = aux2.getLocation();
    aux1.setLocation(aux2Loc);
    aux2.setLocation(aux1Loc);
  } catch (java.lang.ArrayIndexOutOfBoundsException ex) { /* error! bad input to the function*/
   System.exit(1);
  }
}

//Also, you will need to include the other mouselistener implemented methods, just 
//leave them empty
}