Java 如何在不将addMouseListener添加到每个元素的情况下,对JPanel数组的元素使用addMouseListener。?

Java 如何在不将addMouseListener添加到每个元素的情况下,对JPanel数组的元素使用addMouseListener。?,java,swing,jpanel,mouseevent,mouselistener,Java,Swing,Jpanel,Mouseevent,Mouselistener,我正在尝试制作一个国际象棋程序,其中我有一个8x8的JPanel数组,所有这些都需要一个AddMouseStener,但在这个AddMouseStener中,我需要使用该数组的索引才能工作,如下所示: panels[0][0].addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { panels[0][0].setBorder(BorderFactory

我正在尝试制作一个国际象棋程序,其中我有一个8x8的JPanel数组,所有这些都需要一个AddMouseStener,但在这个AddMouseStener中,我需要使用该数组的索引才能工作,如下所示:

panels[0][0].addMouseListener(new MouseAdapter() {

        public void mousePressed(MouseEvent e) {
            panels[0][0].setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
        }

        public void mouseReleased(MouseEvent e) {

        }
    });
因为我有64个JPanel,这意味着我需要复制63次,可能的更改也需要复制。有没有更好、更有效的方法来实现这一点

因为我有64个JPanel,这意味着我需要复制63次

您可以编写一个通用侦听器

MouseListener ml = new MouseAdapter()
{
    @Override
    public void mousePressed(MouseEvent e)
    {
        JPanel panel = (JPanel)e.getSource();
        panel.setBorder(...);
    }
};
然后在循环代码中执行以下操作:

panels[?][?].addMouseListener( ml );

您应该始终尝试编写通用侦听器,以便代码可以重用。

您应该为此使用循环:

for (int r = 0; r < panels.length; ++r) {
    for (int c = 0; c < panels[r].length; ++c) {
        // Do this to fix the "must be final" error:
        final int row = r;
        final int col = c;
        panels[row][col].addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                panels[row][col].setBorder(.....);
            }
            // ..... more
        });
    }
}
这基本上就是使用匿名类的示例在幕后所做的。您还可以保存对面板本身的引用

也可以在MouseeEvent上使用getSource方法:


在这种情况下,您只需要一个鼠标侦听器,就可以将其添加到每个面板。

当您有一个数组时,您必须采取不同的方法

首先,您的类应该实现MouseListener,它有5个抽象方法,但您可能对mouseClicked感兴趣:

public class Example implements MouseListener{

@Override
public void mouseClicked(MouseEvent e) {
     JPanel panel = (JPanel) e.getSource(); // finding which panel is clicked on
}

@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
}  
然后在你班里的某个地方你会做:

for(int i = 0; i < panels.length; i++){
     for(int j = 0; j < panels[0].length; j++){
         panels[0][0].addMouseListener(this);
     }
}

这看起来很棒,但我认为它仍然不起作用,因为我直接需要代码中的索引。我在mousePressed方法中调用一个方法,该方法接受两个整数,行和列,它们是JPanel的索引。知道如何解决这个问题吗?我现在在mousePressed方法中执行for循环,当panels数组的一个元素等于JPanele.getSource,然后传递行和列整数时,我会在其中查找。这似乎很有效,但我想知道你是否可以强调一下这是否正确。@Borisverwoard,这看起来很棒-那么你为什么不试试呢???为什么你认为你需要行/列?我在mousePressed方法中调用了一个方法-这应该是原始问题的一部分。我现在执行一个for循环——我想说一个简单的循环比创建64个鼠标侦听器要好。第一个不起作用,我知道,因为我已经尝试过了。我得到的错误是,变量行和列需要是最终的。请参阅我的编辑以了解如何修复该错误。那只是我的疏忽。他们改变了Java 8中的工作方式,出于某种原因,我认为这是不必要的。1因为我有64个JPanel使用JButton组件而不是面板,使用ActionListener而不是“MouseListener”,并使用工厂方法将侦听器添加到每个按钮。2另见。
public class Example implements MouseListener{

@Override
public void mouseClicked(MouseEvent e) {
     JPanel panel = (JPanel) e.getSource(); // finding which panel is clicked on
}

@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
}  
for(int i = 0; i < panels.length; i++){
     for(int j = 0; j < panels[0].length; j++){
         panels[0][0].addMouseListener(this);
     }
}