gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 05:09:15 26 4
gpt4 key购买 nike

我有一个 Composite,我想在其上跟踪 SWT.MouseEnterSWT.MouseExit 事件。但是,由于 FillLayoutComposite 内部还有另一个 Composite 占据了整个区域。

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

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 永远不会记录鼠标进入/退出事件,除非我暴露了一点它的“区域”。

我可以通过在其 FillLayout 上创建一些边距来暴露一点点 outerComp(注释掉第 21-22 行),但这确实不理想.出于美学原因,我不能在 outerComp 上留出很大的边距,如果我将鼠标快速移到复合 Material 上(我有将我的鼠标非常缓慢地移动到 1 像素的边距上以触发它)。

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

如果 outerComp 有一个 FillLayout 占用了它的所有区域,我还有什么方法可以跟踪这些鼠标事件吗?

最佳答案

您可以做的是向Display 添加一个过滤器,并在处理程序中检查Widget 是否是Event 的来源> 是您的 Composite 的子项。

这应该让您知道如何去做:

public static void main(String[] args)
{
Display display = new Display();
Shell shell = new Shell();
shell.setText("StackOverflow");
shell.setLayout(new GridLayout(2, true));

final Composite left = new Composite(shell, SWT.NONE);
Composite right = new Composite(shell, SWT.NONE);
left.setLayout(new GridLayout(3, true));
right.setLayout(new GridLayout(3, true));

for (int i = 0; i < 6; i++)
{
new Label(left, SWT.NONE).setText("label-" + i);
new Label(right, SWT.NONE).setText("label-" + i);
}

display.addFilter(SWT.MouseMove, new Listener()
{
@Override
public void handleEvent(Event e)
{
if (isChildOrSelf(e.widget, left))
System.out.println(e);
}
});

shell.pack();
shell.open();

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

display.dispose();
}

private static boolean isChildOrSelf(Widget child, Composite parent)
{
if(child == parent)
return true;

for (Control c : parent.getChildren())
{
if (c instanceof Composite)
{
boolean result = isChildOrSelf(child, (Composite)c);
if (result)
return true;
}
else if (c == child)
return true;
}

return false;
}

关于java - 使用 FillLayout 在 Composite 上记录 SWT MouseEnter/Exit 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29267235/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com