Java JLayeredPane:如何检查组件下是否绘制了另一个

Java JLayeredPane:如何检查组件下是否绘制了另一个,java,swing,jlayeredpane,Java,Swing,Jlayeredpane,我有一张红色的窗格。我在上面放置了几个组件。这些组件是扩展jPanel的类。所有构件都放置在同一深度层中。每个组件可能有或可能没有其他组件/组件全部/部分位于其上方/下方。单击组件时,会单击最上面的组件 我如何检查在我单击的点的最下方是否有更多组件?我如何将单击事件“传递”到其中一个组件或下面的许多组件 编辑:一个工作示例 import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseList

我有一张红色的窗格。我在上面放置了几个组件。这些组件是扩展jPanel的类。所有构件都放置在同一深度层中。每个组件可能有或可能没有其他组件/组件全部/部分位于其上方/下方。单击组件时,会单击最上面的组件

我如何检查在我单击的点的最下方是否有更多组件?我如何将单击事件“传递”到其中一个组件或下面的许多组件

编辑:一个工作示例

 import java.awt.*;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
 import java.util.ArrayList;
 import javax.swing.*;

 public class JavaJLayeredPane {
    JFrame frame;
    JLayeredPane layeredPane;
    JPanel Panel1;
    JPanel panel;

 public void createUI()
 {
    frame = new JFrame("Items one ove the other");
    frame.setPreferredSize(new Dimension(600, 400));
    frame.setLayout(new BorderLayout());

    layeredPane = new JLayeredPane();
    frame.add(layeredPane, BorderLayout.CENTER);

    layeredPane.setBounds(0, 0, 600, 400);

    ArrayList<Color> colorList = new ArrayList<Color>();
    colorList.add(Color.red);
    colorList.add(Color.yellow);
    colorList.add(Color.blue);
    colorList.add(Color.green);
    colorList.add(Color.cyan);

    for (int i=0; i<5; i++){
    String mytext="no"+ i;
    Panel1 = new myarea(mytext);
    Panel1.setBackground(colorList.get(i));
    if (i==0){Panel1.setBounds(210, 110, 20, 20);}
    if (i==1){Panel1.setBounds(200, 100, 150, 150);}
    if (i==2){Panel1.setBounds(250, 110, 170, 120);}
    if (i==3){Panel1.setBounds(180, 130, 110, 110);}
    if (i==4){Panel1.setBounds(450, 150, 50, 50);}
    layeredPane.add(Panel1, new Integer(0), 0);
    }

    panel = new JPanel();
    frame.add(panel);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
  }



public static void main(String[] args) {
    JavaJLayeredPane overlapPane = new JavaJLayeredPane();
            overlapPane.createUI();
}

   public class myarea extends JPanel implements  MouseListener{
        public String areaname;

    public myarea(String myname) {
        addMouseListener(this);
        areaname=myname;
    }

//LISTENERS    
    @Override
 public void mousePressed(MouseEvent evt){
}
    @Override
public void mouseReleased(MouseEvent evt){
}
    @Override
public void mouseClicked(MouseEvent evt){
    if(evt.getButton() == MouseEvent.BUTTON1){
    JOptionPane.showMessageDialog(null,areaname ) ;    
    }

  }
    @Override
  public void mouseEntered(MouseEvent evt){
  }
    @Override
  public void mouseExited(MouseEvent evt){
  }
 }


 }
import java.awt.*;
导入java.awt.event.MouseEvent;
导入java.awt.event.MouseListener;
导入java.util.ArrayList;
导入javax.swing.*;
公共类JavaJLayeredPane{
JFrame框架;
JLayeredPane layeredPane;
JPanel Panel 1;
JPanel小组;
public void createUI()
{
框架=新的JFrame(“一个项目高于另一个项目”);
frame.setPreferredSize(新尺寸(600400));
frame.setLayout(新的BorderLayout());
layeredPane=新的JLayeredPane();
frame.add(layeredPane,BorderLayout.CENTER);
分层窗格.立根(0,0,600,400);
ArrayList colorList=新的ArrayList();
颜色列表。添加(颜色。红色);
颜色列表。添加(颜色。黄色);
颜色列表。添加(颜色。蓝色);
颜色列表。添加(颜色。绿色);
colorList.add(Color.cyan);
对于(int i=0;i基本上有两项任务:

  • 访问同一层中接收mouseEvent的组件下方的组件,并找到包含鼠标位置的第一个组件
  • 如果发现,手动调度事件(并让它处理进一步的调度,如有必要)
JLayeredPane api有助于第一种方法,而组件有一种方法来完成第二种方法——唯一需要注意的是坐标变换,SwingUtilities的辅助方法在坐标变换中发挥作用

@Override
public void mouseClicked(MouseEvent evt) {
    if (!SwingUtilities.isLeftMouseButton(evt)) return;
    Component[] siblings = layeredPane.getComponentsInLayer(JLayeredPane.getLayer(this));
    int pos = layeredPane.getPosition(this);
    for (Component sibling : siblings) {
        // interested in siblings below
        if (layeredPane.getPosition(sibling) > pos) {
            // convert coordinates
            Point p = SwingUtilities.convertPoint(this, evt.getX(), evt.getY(), sibling);
            if (sibling.contains(p)) {
                // convert event
                MouseEvent dispatch = SwingUtilities.convertMouseEvent(
                        this, evt, sibling);
                // manually dispatch the event
                sibling.dispatchEvent(dispatch);
                break;
            }
        }

    }
    // do my own work
    System.out.println(getName() + evt);
}
基本上有两项任务:

  • 访问同一层中接收mouseEvent的组件下方的组件,并找到包含鼠标位置的第一个组件
  • 如果发现,手动调度事件(并让它处理进一步的调度,如有必要)
JLayeredPane api有助于第一种方法,而组件有一种方法来完成第二种方法——唯一需要注意的是坐标变换,SwingUtilities的辅助方法在坐标变换中发挥作用

@Override
public void mouseClicked(MouseEvent evt) {
    if (!SwingUtilities.isLeftMouseButton(evt)) return;
    Component[] siblings = layeredPane.getComponentsInLayer(JLayeredPane.getLayer(this));
    int pos = layeredPane.getPosition(this);
    for (Component sibling : siblings) {
        // interested in siblings below
        if (layeredPane.getPosition(sibling) > pos) {
            // convert coordinates
            Point p = SwingUtilities.convertPoint(this, evt.getX(), evt.getY(), sibling);
            if (sibling.contains(p)) {
                // convert event
                MouseEvent dispatch = SwingUtilities.convertMouseEvent(
                        this, evt, sibling);
                // manually dispatch the event
                sibling.dispatchEvent(dispatch);
                break;
            }
        }

    }
    // do my own work
    System.out.println(getName() + evt);
}
基本上有两项任务:

  • 访问同一层中接收mouseEvent的组件下方的组件,并找到包含鼠标位置的第一个组件
  • 如果发现,手动调度事件(并让它处理进一步的调度,如有必要)
JLayeredPane api有助于第一种方法,而组件有一种方法来完成第二种方法——唯一需要注意的是坐标变换,SwingUtilities的辅助方法在坐标变换中发挥作用

@Override
public void mouseClicked(MouseEvent evt) {
    if (!SwingUtilities.isLeftMouseButton(evt)) return;
    Component[] siblings = layeredPane.getComponentsInLayer(JLayeredPane.getLayer(this));
    int pos = layeredPane.getPosition(this);
    for (Component sibling : siblings) {
        // interested in siblings below
        if (layeredPane.getPosition(sibling) > pos) {
            // convert coordinates
            Point p = SwingUtilities.convertPoint(this, evt.getX(), evt.getY(), sibling);
            if (sibling.contains(p)) {
                // convert event
                MouseEvent dispatch = SwingUtilities.convertMouseEvent(
                        this, evt, sibling);
                // manually dispatch the event
                sibling.dispatchEvent(dispatch);
                break;
            }
        }

    }
    // do my own work
    System.out.println(getName() + evt);
}
基本上有两项任务:

  • 访问同一层中接收mouseEvent的组件下方的组件,并找到包含鼠标位置的第一个组件
  • 如果发现,手动调度事件(并让它处理进一步的调度,如有必要)
JLayeredPane api有助于第一种方法,而组件有一种方法来完成第二种方法——唯一需要注意的是坐标变换,SwingUtilities的辅助方法在坐标变换中发挥作用

@Override
public void mouseClicked(MouseEvent evt) {
    if (!SwingUtilities.isLeftMouseButton(evt)) return;
    Component[] siblings = layeredPane.getComponentsInLayer(JLayeredPane.getLayer(this));
    int pos = layeredPane.getPosition(this);
    for (Component sibling : siblings) {
        // interested in siblings below
        if (layeredPane.getPosition(sibling) > pos) {
            // convert coordinates
            Point p = SwingUtilities.convertPoint(this, evt.getX(), evt.getY(), sibling);
            if (sibling.contains(p)) {
                // convert event
                MouseEvent dispatch = SwingUtilities.convertMouseEvent(
                        this, evt, sibling);
                // manually dispatch the event
                sibling.dispatchEvent(dispatch);
                break;
            }
        }

    }
    // do my own work
    System.out.println(getName() + evt);
}


听起来JLayeredPane在我看来真的很糟糕。也许一个可运行的示例可能会改变我的想法。@peeskillet。我的案例太复杂了,无法在这里发布。为什么使用不好?在JLayeredPane中将一个组件放置在另一个组件上并没有错,当需要用鼠标访问所有重叠的组件时也并没有错。有吗?如果要将所有组件放在同一层上,为什么还要使用JlayeredPane?这就是我想说的。我同意,将所有组件放在同一层上听起来有点可疑,但您可以将MouseListener添加到JlayeredPane本身,然后遍历其组件以查看哪个组件位于同一层鼠标点击的要点。同样,没有人会问你整个程序,但你的案例肯定不会太复杂,如果你把它归结为一个,是的,需要努力才能产生的东西,但往往是值得努力的。你的问题本质上很简单,但对于我来说,构建一个答案并测试它,我必须创建我的答案自己的,正如你所说的“很难”因为这是你的问题,我的偏好是创造这个工具的努力应该是你的,而不是我的,但是也许如果你等待更长的时间,别人会来,创造自己的,并为你解决。如果这不很快发生,考虑重新考虑你的决定不创造一个。如果你改变主意,请做。通知我看一下。目前,我正在注销。运气好!听起来JLayeredPane在我看来使用得很糟糕。也许一个可运行的示例可能会改变我的想法。@peeskillet。我的案例太复杂了,无法在这里发布。为什么使用得不好?在JLayeredPane中将一个组件放置在另一个组件上没有问题,而在需要时也没有问题o能够通过鼠标访问所有重叠的组件。有吗?如果要将所有组件放在同一层上,为什么还要使用JlayeredPane?这就是我的意思。我同意,让所有组件都在同一层上听起来有点可疑,但你可以将鼠标侦听器添加到JlayeredPane本身,然后再添加到iter仔细检查它的组件,看看鼠标点击的位置是哪个。同样,没有人会问你整个程序,但你的案例肯定不会太复杂,如果你把它归结为一个,是的,需要努力才能产生的东西,但往往是值得努力的。你的问题本质上很简单,但我同意构建一个答案并测试它,我必须创建我自己的答案,正如你所说的“很难”,因为这是你的问题