[英]How can I stop an SWT composite control from firing a MouseExit event when the mouse enters a component control?
I have subclassed org.eclipse.swt.widgets.Composite to create a new composite control.我已经将 org.eclipse.swt.widgets.Composite 子类化来创建一个新的复合控件。 I want to capture MouseEnter and MouseExit events in this control but the problem I have is that when the mouse is hovered over a component in the control (say, a Label) the MouseExit event is fired, even though the label is part of the whole Composite.
我想在此控件中捕获 MouseEnter 和 MouseExit 事件,但我遇到的问题是,当鼠标悬停在控件中的组件(例如标签)上时,会触发 MouseExit 事件,即使标签是整个组件的一部分合成的。
Is there any way to stop this event being fired?有没有办法阻止这个事件被触发? I only want to see the event if the mouse leaves the total boundary of the control.
如果鼠标离开控件的总边界,我只想查看事件。 Here is some example code to show you what I mean.
这是一些示例代码,向您展示我的意思。
public class MyControl extends Composite{
Label label;
public MyControl(Composite parent, String label) {
super(parent, SWT.NONE);
label = new Label(this,0);
label.setText(label);
this.addListener(SWT.MouseEnter, new Listener() {
@Override
public void handleEvent(Event event) {
// handle this event
}
});
this.addListener(SWT.MouseExit, new Listener() {
@Override
public void handleEvent(Event event) {
// handle this event
}
});
}
} }
You can simply put an logic in your event handler to see if the control is a child of your new control and ignore it.您可以简单地在事件处理程序中放置一个逻辑,以查看该控件是否是新控件的子项并忽略它。 Something like the following: (I haven't tested the code, but I think this should work for you)
类似于以下内容:(我还没有测试过代码,但我认为这对你有用)
this.addListener(SWT.MouseExit, new Listener() {
@Override
public void handleEvent(Event event) {
for (Control control : ParentClass.this.getChildren()) {
if (control == event.item)
return;
}
// handler logic goes here
}
});
I solved the same problem (MouseExit is sent to a Composite when the mouse enters one of its children) with an event filter.我用一个事件过滤器解决了同样的问题(当鼠标进入它的一个孩子时,MouseExit 被发送到一个 Composite )。 Here's the code.
这是代码。
public class MouseTracker implements Listener {
static MouseTracker instance;
private static class Item {
Composite composite;
boolean inside;
MouseTrackListener listener;
}
private List<Item> listeners = new ArrayList<>();
private MouseTracker() {
}
public static MouseTracker getInstance() {
if (instance == null)
instance = new MouseTracker();
return instance;
}
private void install() {
Display.getCurrent().addFilter(SWT.MouseEnter, this);
Display.getCurrent().addFilter(SWT.MouseExit, this);
Display.getCurrent().addFilter(SWT.Resize, this);
}
private void uninstall() {
Display.getCurrent().removeFilter(SWT.MouseEnter, this);
Display.getCurrent().removeFilter(SWT.MouseExit, this);
Display.getCurrent().removeFilter(SWT.Resize, this);
}
public void addMouseTrackListener(Composite c, MouseTrackListener listener) {
if (listeners.isEmpty())
install();
Item i = new Item();
i.composite = c;
i.inside = false;
i.listener = listener;
listeners.add(i);
}
public void removeMouseTrackListener(Composite c, MouseTrackListener listener) {
listeners.removeIf((i) -> i.composite == c && i.listener == listener);
if (listeners.isEmpty())
uninstall();
}
public void handleEvent(Event e) {
boolean hasDisposed = false;
for (Item i : listeners) {
Composite c = i.composite;
if (c.isDisposed())
hasDisposed = true;
else {
Point p = Display.getCurrent().getCursorLocation();
boolean containsMouse = c.getBounds().contains(c.getParent().toControl(p));
if (i.inside != containsMouse) {
i.inside = containsMouse;
if (containsMouse)
i.listener.mouseEnter(new MouseEvent(e));
else
i.listener.mouseExit(new MouseEvent(e));
}
}
}
if (hasDisposed) {
listeners.removeIf((i) -> i.composite.isDisposed());
if (listeners.isEmpty())
uninstall();
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.