使用FillLayout在Composite上记录SWT MouseEnter / Exit事件

时间:2015-03-25 21:51:30

标签: java swt mouseevent

我有一个Composite,我想跟踪SWT.MouseEnterSWT.MouseExit个事件。但是,由于CompositeComposite在其中有另一个FillLayout消耗了整个区域。

一些示例代码来说明我正在做什么:

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

public class EventListenerTest {

    public static void main(String[] args) {

        Display display = new Display();
        Shell shell = new Shell(display);

        // Set up the outer Composite
        Composite outerComp = new Composite(shell, SWT.BORDER);
        FillLayout fl = new FillLayout();
        // fl.marginHeight = 15;
        // fl.marginWidth = 15;
        outerComp.setLayout(fl);

        // Set up a nested Composite
        Composite innerComp = new Composite(outerComp, SWT.BORDER);

        // Set a listener on the outer Composite for a MouseEnter event
        outerComp.addListener(SWT.MouseEnter, new Listener() {
            @Override
            public void handleEvent(Event e) {
                System.out.println("Mouse ENTER event");
            }

        });

        // Similarly, for a MouseExit event
        outerComp.addListener(SWT.MouseExit, new Listener() {
            @Override
            public void handleEvent(Event e) {
                Composite comp = (Composite) e.widget;
                // Don't report if positioned over a child control
                for (Control child : comp.getChildren()) {
                    if (!child.getBounds().contains(new Point(e.x, e.y)))
                        System.out.println("Mouse EXIT event");
                }
            }

        });

        outerComp.pack();
        outerComp.layout();

        shell.pack();
        shell.open();
        while (!shell.isDisposed()) {
          if (!display.readAndDispatch()) {
            display.sleep();
          }
        }

        display.dispose();
        return;
      }
}

不幸的是,由于innerComp填充了其父级的全部事实,outerComp永远不会记录鼠标进入/退出事件,除非我暴露了一点点它的“区域”。

我可以通过在outerComp(注释掉第21-22行)上创建一些边距来暴露一点FillLayout,但这实际上并不理想。出于审美原因,我不能在outerComp上获得巨大的余量,如果我将鼠标快速移动到复合材料上,则将边距大小减小到1并不会始终检测到鼠标事件(我必须移动我的鼠标非常慢慢超过1px的余量,以便触发)。

从我的项目的设计角度来看,我实际上不应该知道outerComp包含的内容(或控件嵌套的深度),因此在其子项上设置事件侦听器也不理想。 / p>

如果outerComp消耗了所有区域的FillLayout,我仍然可以在{{1}}上跟踪这些鼠标事件吗?

1 个答案:

答案 0 :(得分:3)

您可以做的是在Display和处理程序中添加过滤器,检查Widget的来源Event是否是您{{1}的孩子}}

这应该让你知道如何做到这一点:

Composite