The code below shows, that:
1) HOVER is totally ignored with composite. How to enable?
2) ENTER/EXIT are tracked, but when mouse entered child control region, parent composite receives EXIT event. How to make that entre area of a composite would serve as belonging to composite?
public class TryHover {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
Composite composite = new Composite(shell, SWT.BORDER);
composite.setLayout(new GridLayout(1, false));
Label label1 = new Label(composite, SWT.BORDER);
label1.setText("Label 1");
Label label2 = new Label(composite, SWT.BORDER);
label2.setText("Label 2");
composite.addListener(SWT.MouseEnter, new Listener() {
@Override
public void handleEvent(Event event) {
System.out.println("ENTER");
}
});
composite.addListener(SWT.MouseExit, new Listener() {
@Override
public void handleEvent(Event event) {
System.out.println("EXIT");
}
});
composite.addListener(SWT.MouseHover, new Listener() {
@Override
public void handleEvent(Event event) {
System.out.println("HOVER");
}
});
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
}
UPDATE
Yes, agree, if mouse is slow, it produces HOVER too.
Then the question is about ENTER/EXIT only: how to turn EXITs of on child controls?
SWT.MouseHover
is only triggered when the mouse is located over the Composite
and doesn't move for a fraction of a second.
SWT.MouseMove
is triggered on each movement of the mouse over the Composite
.
So it really depends on what you want to achieve here.
As for the second part of your question: SWT does not propagate events up the widget hierarchy (with some exceptions).
You can however implement your own logic to determine when to listen to the events.
SWT.MouseExit
: Get the coordinates of the mouse and check if any of the children contains the mouse. If so, do nothing, if not, you left the Composite
.SWT.MouseEnter
: This is a bit more tricky. I came up with a solution that keeps track of the current Widget
the mouse is moving over using a filter on the display. When you enter the Composite
, you can check if the previous widget was a child. If so, do nothing.private static Widget mouseControl = null;
public static void main(String[] args)
{
Display display = new Display();
/* Overall, keep track of the Widget the mouse is moving over */
display.addFilter(SWT.MouseMove, new Listener()
{
@Override
public void handleEvent(Event e)
{
mouseControl = e.widget;
}
});
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
final Composite composite = new Composite(shell, SWT.BORDER);
composite.setLayout(new GridLayout(1, false));
Label label1 = new Label(composite, SWT.BORDER);
label1.setText("Label 1");
Label label2 = new Label(composite, SWT.BORDER);
label2.setText("Label 2");
composite.addListener(SWT.MouseEnter, new Listener()
{
@Override
public void handleEvent(Event event)
{
/* Check if the mouse was previously moving over a child (you could
* even do recursive search here) */
for (Control child : composite.getChildren())
{
if (child.equals(mouseControl))
return;
}
System.out.println("ENTER");
}
});
composite.addListener(SWT.MouseExit, new Listener()
{
@Override
public void handleEvent(Event event)
{
/* Check if the mouse is now located over a child (you could
* even do recursive search here) */
for (Control child : composite.getChildren())
{
if (child.getBounds().contains(new Point(event.x, event.y)))
return;
}
System.out.println("EXIT");
}
});
composite.addListener(SWT.MouseHover, new Listener()
{
@Override
public void handleEvent(Event event)
{
System.out.println("HOVER");
}
});
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With