Java JPanel上的mouseListener出现问题
我对JPanel中的mouseListener有问题。 我在JPanel上添加了包含图像(大小为600 x 600)的JLabel,并为JPanel添加了mouseListener 每次我点击图像时,图像都会变成另一个图像,这很好。但是,问题是,只有单击图像的右侧或中心,图像才会更改为另一个图像。当我点击顶部或左侧时,图像不会改变。这让我很困惑。我希望在单击图像显示中的任意位置时,图像会更改为另一个图像Java JPanel上的mouseListener出现问题,java,mouse,listener,Java,Mouse,Listener,我对JPanel中的mouseListener有问题。 我在JPanel上添加了包含图像(大小为600 x 600)的JLabel,并为JPanel添加了mouseListener 每次我点击图像时,图像都会变成另一个图像,这很好。但是,问题是,只有单击图像的右侧或中心,图像才会更改为另一个图像。当我点击顶部或左侧时,图像不会改变。这让我很困惑。我希望在单击图像显示中的任意位置时,图像会更改为另一个图像 private final int SECOND= 1; private final int
private final int SECOND= 1;
private final int FIRST = 0;
int imageCounter = 0;
JLabel picture;
JPanel panel;
...
private mainLayout () {
GridBagLayout m = new GridBagLayout();
Container c = (Container)getContentPane();
GridBagConstraints con;
c.setLayout (m);
picture = new JLabel();
picture.setIcon(getImages(myImage.get(imageCounter).get(FIRST))); //first Image
panel = new JPanel();
con = new GridBagConstraints();
con.anchor=GridBagConstraints.CENTER;
con.gridy = 1; con.gridx = 0;
m.setConstraints(panel, con);
c.add(panel);
panel.add(picture); //add the pictures
panel.addMouseListener(l);
....
}
MouseListener l = new MouseAdapter(){
public void mouseClicked (MouseEvent e)
{
Point p = e.getPoint();
if((panel.getBounds().contains(p))
picture.setIcon(getImages(myImage.get(imageCounter).get(SECOND)));
}
};
你确定你真的在点击吗?只有在完全相同的位置按下和释放鼠标时,才会触发鼠标单击事件。如果您在单击时鼠标移动得很小,则不会触发事件。您确定您确实在单击吗?只有在完全相同的位置按下和释放鼠标时,才会触发鼠标单击事件。如果鼠标在单击时移动得很小,则不会触发事件。出于好奇,为什么要使用JLabel显示图像?您最好编写一个ImagePanel类来扩展JPanel并重写paint()方法来绘制自己的图形。然后,您可以将鼠标听筒直接连接到面板上。出于好奇,您为什么要使用JLabel显示图像?您最好编写一个ImagePanel类来扩展JPanel并重写paint()方法来绘制自己的图形。然后,您可以将鼠标侦听器直接连接到面板。问题似乎出现在以下不必要的代码中:
Point p = e.getPoint();
if((panel.getBounds().contains(p))
鼠标侦听器位于面板上,因此鼠标坐标将相对于面板左上角panel.getBounds()
获取面板相对于其父容器的边界
值得注意的是,鼠标事件的行为非常奇怪。它们会“冒泡”,直到碰到连接了鼠标侦听器的组件。因此,添加鼠标侦听器实际上会改变组件的行为。将侦听器添加到父级可能会错过事件,具体取决于组件的确切设置方式(可能会任意更改)。解决这个问题的方法有很多,但没有一种是好的。问题似乎就在这段不必要的代码中:
Point p = e.getPoint();
if((panel.getBounds().contains(p))
鼠标侦听器位于面板上,因此鼠标坐标将相对于面板左上角panel.getBounds()
获取面板相对于其父容器的边界
值得注意的是,鼠标事件的行为非常奇怪。它们会“冒泡”,直到碰到连接了鼠标侦听器的组件。因此,添加鼠标侦听器实际上会改变组件的行为。将侦听器添加到父级可能会错过事件,具体取决于组件的确切设置方式(可能会任意更改)。有很多方法可以解决这个问题,但没有一种是好的。您可能遇到的问题与我遇到的相同,即您的事件在您的层次结构中被吞噬,正如前面的海报所暗示的那样。关于中工国际商用飞机有限公司的回复,只要您知道后果,您是否扩展
JPanel
或JLabel
,其实并不重要JPanel
为您提供了更多的功能,并且已经内置了许多有用的东西。但让我们举一个简单的例子,你有以下几点:
包含JPanel
的JFrame
,称之为JParent
JParent
有一组专用的鼠标侦听器
JParent
包含添加到其组件中的子JPanel
,名为JChild
JChild
也有自己的一组鼠标侦听器
单击未被JChild
占用的区域时发生了什么?您将得到JParent
的侦听器的响应。如果在JChild
可见的区域中单击,则只有JChild
的鼠标事件才会触发
因此,在调试时要非常小心,因为Java的swing可能具有不同于其他绘制简单表单/GUI实现的行为。事件基本上是一次性的,最低级别的组件获得第一个DIB。如果仍然尝试触发父事件,则x/y坐标将基于子事件而不是父事件。我仍在努力为自己找到一个好的解决方案,因为我需要专门访问父对象以将对象移动到其他位置
我能想到的最好的方法是调试/思考以下两个想法:
a) 让每个组件都包含自己独有的事件集,并尝试防止“冒泡”效应发挥作用。
b) 处理父级上的所有事件
我更喜欢a,因为它避免了令人讨厌的事情,比如检查组件类只是为了弄清楚您想要什么样的反应(例如,显示什么样的右键单击菜单)
编辑:所以你可以用我发现的任何一种方法来处理这个问题。您可以使用dispatchEvent消息将事件转发回链的上游。在我的例子中,我必须吞噬第一个事件(或改变它),并发送x-y位置,就好像它们相对于父事件一样(使用偏移量)。我认为更好的方法是通过转发,因为这样可以封装您的所有单个组件。您可能遇到的问题与我遇到的问题相同,即您的事件在您的层次结构中被吞噬,正如前面的海报所暗示的。关于中工国际商用飞机有限公司的回复,只要您知道后果,您是否扩展
JPanel
或JLabel
,其实并不重要JPanel
为您提供了更多的功能,并且已经内置了许多有用的东西。但让我们举一个简单的例子,你有以下几点:
包含以下内容的JFrame