单击jPanel(Java)时如何调用函数?

Posted

技术标签:

【中文标题】单击jPanel(Java)时如何调用函数?【英文标题】:How to call a function when I click on a jPanel (Java)? 【发布时间】:2012-04-15 13:22:18 【问题描述】:

我正在使用 Java 中的 Netbeans IDE。

我有一个带有一个 JPanel 的表单。 每个 JPanel 都有一个 3x3 的 gridLayout 并且在每个地方都有一个表示数字 [0,1,2,3,4,5,6,7,8] 的图像(图像是使用自定义类创建的,而不仅仅是适合实验室中的图像)。

当用户单击它们时,我希望能够在面板中交换两个图像(第一次单击:无操作,第二次单击:切换 jPanel 组件中安装的两个图像)。

我已经创建了一个函数 exchangeComponents 和一个测试代码(比如:

exchangeComponents (0,8,jPanel1)

它正确地交换位于位置 1(第 1 行第 1 列)和位置 2(第 3 行第 3 列)的图像。

创建的函数如下:

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);
   

我想当用户单击 jPanel1 上的一个图像时,我需要一个调用函数 exchangeComponents() 的事件,但我应该怎么做呢?以及如何检查用户选择了哪些组件(图像)? 我只知道,当我创建一个 Button 时,如果单击它(从 IDE 中)一个类似的事件

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

创建并执行我填写的代码。

提前感谢您的任何提示。

【问题讨论】:

【参考方案1】:

您需要将相同的鼠标侦听器添加到您的所有 JLabel 或您为图像所拥有的任何容器中,例如:

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

等等,然后用MouseEvent.getSource();检测你点击了哪个Jlabel,像这样

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);
  

如果您没有对图像使用 JLabel,请将代码中的 JLabel 替换为您正在使用的任何内容...

编辑: 抱歉,我不认为我说得不清楚,但是您使用方法 exchangeComponents 的类必须实现 MouseListener。然后,在 mouseClicked 事件中输入我为它提供的代码。确保在您的课程中包含变量 hasclicked1click1label。让你上课是这样的

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

【讨论】:

谢谢。很清楚.. 但是使用 img1.addMouseListener(this);我传递了表单本身,它显示“错误:预期 MouseListener”。那又怎样? 好吧,我做到了(创建了一个实现 MouseListener 的类 getComponent)并使用了 img1.addMouseListener(new ComponentListener())。现在的问题是.. 我为每个组件添加了一个侦听器,但是当我单击任何组件(图像)时,根本不会触发事件 对不起,我觉得我说的不是很清楚,但是你的类需要实现MouseListener,那么你需要将监听器添加到你正在切换的每个组件中。 @dragonml【参考方案2】:

首先,从技术上讲,它是方法而不是函数。 有几种方法可以做到这一点。您可以继续使用 actionListener,但是您可能需要按钮或其他东西。 或者您可以使用 MouseListener,并检测面板特定区域上的点击。 对于切换算法,可能是 2 个图像的数组。有一个变量每次点击都会增加 1。当变量为 2 时,它会重置为 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

在第一次点击时,点击的图像进入第一个数组槽,因为用户点击了一次。

clickImage = imageArray[clicks];

在第二次点击时,另一个点击的图像会进入第二个阵列槽,因为已检测到 2 次点击。在这种情况下,您的 exchangeComponents 方法将位于侦听器方法的末尾,参数为 imageArray[1]、imageArray[2]、.

您可以将其应用于整数或其他任何内容,只需将值保存在数组中并使用递增和重置变量。

【讨论】:

以上是关于单击jPanel(Java)时如何调用函数?的主要内容,如果未能解决你的问题,请参考以下文章

Java JPanel repaint() 问题?

Java Swing 在单击我要删除的 jpanel 中存在的 Jbutton 时删除 Jpanel

Java 的 JPanel 子类中重写父类的 paint 方法 会被自动调用,请问调用的条件或时机

单击第二次链接PrimeFaces时,构造函数不会调用

如何在 JPanel 中绘图? (摇摆/图形Java)

如何在单击剑道网格每一行时调用单个函数