Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm working with Netbeans IDE in Java.

I've a form with one JPanel. Each JPanel has a gridLayout 3x3 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.

like image 596
dragonmnl Avatar asked Apr 01 '12 18:04

dragonmnl


People also ask

Can you add an action listener to a JPanel?

First off as @Sage mention in his comment a JPanel is rather a container than a component which do action. So you can't attach an ActionListener to a JPanel .

What does JPanel do in Java?

JPanel, a part of the Java Swing package, is a container that can store a group of components. The main task of JPanel is to organize components, various layouts can be set in JPanel which provide better organization of components, however, it does not have a title bar.

Can a JPanel contain JFrame?

These classes are imported and then used in many GUI applications. We use the last, Graphics, to render visuals (e.g., figures, pictures, and even text) in a JPanel that contains the graphics part of a JFrame.

What is the difference between JPanel and JFrame?

JPanel serves as a general purpose container, while JFrame is a window commonly used for stand-alone applications, like a warning window, or a notification window. 2. JPanel represents an area used for more complex operations or applications.


2 Answers

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
}
like image 182
DankMemes Avatar answered Sep 29 '22 05:09

DankMemes


First of all, to be technical it's methods not functions. There are a couple of ways you could do this. You could go ahead with actionListener, but then you would probably need buttons or something. Or you could use MouseListener, and detect clicks over a certain region of the panel. For the switching algorithm, perhaps an array of 2 images. There is a variable that increases by 1 every click. When the variable is 2, it resets back to 0.

clicks++; //every time the mouse is clicked; clicks starts out at 0
if(clicks == 2){
clicks = 0; //at the end of the listener method
}

On the first click the clicked image goes into the first array slot, because the user has clicked once.

clickImage = imageArray[clicks];

On the second click, the other clicked image goes to the second array slot, because 2 clicks have been detected. In this case, your exchangeComponents method would go at the end of the listener method, with the arguments being imageArray[1], imageArray[2], .

You can apply this to ints or whatever, just save the value in an array and use an incrementing and resetting variable.

like image 43
Jimmt Avatar answered Sep 29 '22 05:09

Jimmt