开发者

Passing events to parent

开发者 https://www.devze.com 2023-01-18 04:22 出处:网络
I\'d like to create an app where some events are supposed to be handled as if they were delivered to parent containers. For example I\'ve got a JPa开发者_开发问答nel which contains JLabel. The top JPa

I'd like to create an app where some events are supposed to be handled as if they were delivered to parent containers. For example I've got a JPa开发者_开发问答nel which contains JLabel. The top JPanel implements mousepress and dragging right now. What do I need to do, in order to make the events look like they arrived to JPanel instead of the label itself. (changing source object is important)

Is there some better solution than actually implementing the events and replicating them in the parent? (this would get tedious after some objects with >5 children).


At your event listener, you can dispatch the event to the parent component.

Being myEvent the event handling function argument:

Component source=(Component)myEvent.getSource();
source.getParent().dispatchEvent(myEvent);

But this solution implies creating a new EventListener for each element to add.

So, you could create a single event handler and reuse it, adding it to all the chosen children, like this:

final Container parent=this; //we are a the parent container creation code
MouseListener myCommonListener=new MouseListener() {
    @Override
    public void mouseClicked(MouseEvent e) {
        parent.dispatchEvent(e);
    }
    @Override
    public void mouseEntered(MouseEvent e) {
        parent.dispatchEvent(e);
    }
    @Override
    public void mouseExited(MouseEvent e) {
        parent.dispatchEvent(e);
    }
    @Override
    public void mousePressed(MouseEvent e) {
        parent.dispatchEvent(e);
    }
    @Override
    public void mouseReleased(MouseEvent e) {
        parent.dispatchEvent(e);
    }
};

JLabel label=new JLabel("This is the first Label");
label.addMouseListener(myCommonListener);

JLabel label2=new JLabel("This is the second Label");
label2.addMouseListener(myCommonListener);
//... and so on 


You should convert event before dispatching it to the parent. Conversion includes coordinates translation to parent-relative.

public class RedispatchingMouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener{

    public void mouseClicked(MouseEvent e) {
        redispatchToParent(e);
    }

    public void mousePressed(MouseEvent e) {
        redispatchToParent(e);
    }

    public void mouseReleased(MouseEvent e) {
        redispatchToParent(e);
    }

    public void mouseEntered(MouseEvent e) {
        redispatchToParent(e);
    }

    public void mouseExited(MouseEvent e) {
        redispatchToParent(e);
    }

    public void mouseWheelMoved(MouseWheelEvent e){
        redispatchToParent(e);
    }

    public void mouseDragged(MouseEvent e){
        redispatchToParent(e);
    }

    public void mouseMoved(MouseEvent e) {
        redispatchToParent(e);
    }

    private void redispatchToParent(MouseEvent e){
        Component source = (Component) e.getSource();
        MouseEvent parentEvent = SwingUtilities.convertMouseEvent(source, e, source.getParent());
        source.getParent().dispatchEvent(parentEvent);
    }
}


Mouse events are automatically targeted to the deepest component that has mouse listeners.

Because of this, to achieve your goal, you can simply remove all mouse listeners on the JLabel and it will never get picked as the target for mouse events.

The following code will disable mouse listeners on the given components and their children recursively:

public static void disableMouseForComponent(Component... components) {
    for (Component c : components) {
        if (c instanceof Container) {
            disableMouseForComponent(((Container) c).getComponents());
        }
        for (MouseListener l : c.getMouseListeners()) {
            c.removeMouseListener(l);
        }
        for (MouseMotionListener l : c.getMouseMotionListeners()) {
            c.removeMouseMotionListener(l);
        }
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消