SWT event propagation
Asked Answered
U

1

9

I'm trying to detect click events on a Composite control that contains a number of other composites. I tried:

topComposite.addMouseListener(new MouseListener() {
        ...
        @Override
        public void mouseUp(MouseEvent arg0) {
            logger.info("HERE");
        });
});

But the event never fires. I assumed that when a mouse event occurred on a child it would propagate up the chain but that doesn't happen. How do I do this?

Underprop answered 29/8, 2011 at 3:21 Comment(0)
D
12

In SWT, the general rule is that events do not propagate. The main exception to this, is the propagation of traverse events - which is pretty complicated to describe.

The easy answer to your problem is that you must add the listener to all the children of you Composite - recursively!

E.g. like this

public void createPartControl(Composite parent) {
    // Create view...

    final MouseListener ma = new MouseAdapter() {
        @Override
        public void mouseDown(MouseEvent e) {
            System.out.println("down in " + e.widget);
        }
    };
    addMouseListener(parent, ma);
}

private void addMouseListener(Control c, MouseListener ma) {
    c.addMouseListener(ma);
    if (c instanceof Composite) {
        for (final Control cc : ((Composite) c).getChildren()) {
            addMouseListener(cc, ma);
        }
    }
}

The clicked-upon widget is found in e.widget as seen above. An important issue is to remember to do this again if you add more Controls later.

Dermatosis answered 29/8, 2011 at 6:33 Comment(2)
alternatively, if you do not want t add so many listeners - you can use a workaround. Capture ALL occured MouseEvents by composite.getDisplay().addFilter(SWT.KeyDown, new Listener() {...} and somehow pick the relevant events.Acerbate
@Acerbate This is indeed possible as well, but be careful to deregister the listener again :-)Dermatosis

© 2022 - 2024 — McMap. All rights reserved.