Domanda

I have a JLayeredPane. On that I place several components. Those components are classes that extend jPanel. All components are placed in the same depth layer. Each component may or may not have other component/components totally/partially above/below it. When I click on the components the topmost is clicked.

How do I check if there are more components below the topomost at the point where I clicked? How can I "pass" the click event to one of those or to many of those components below?

EDIT: A working example

 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){
  }
 }


 }

If we click on a rectangle that is abode another we get it's name. How do we check if there is another rectangle below, and if yes, how do we get it's properties?

È stato utile?

Soluzione

Basically two tasks:

  • visit the components in the same layer that are below the one that receives the mouseEvent and find the first that contains the mouse location
  • if found, manually dispatch the event (and let it handle further dispatches, if necessary)

JLayeredPane api helps with the first, and Component has a method to do the second - the only thingy that needs attention is coordinate transformation where SwingUtilities' helper methods come into play

@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);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top