我正在为Eclipse插件实现自定义预览/工具提示。它使用SWT中的Shell,删除其所有修剪并在其中放置文本框。看起来不错。但是现在我需要在光标移出shell窗口时处理shell,我遇到了一些问题:
将mousemoveListener附加到shell是否有意义?首先我是这样做的,但后来我意识到这个监听器只捕获shell中发生的鼠标移动事件。我如何抓住鼠标离开外壳以便我可以处理它?</ p>
谢谢和问候, Krt_Malta
答案 0 :(得分:2)
将MouseTrackListener与MouseTrackAdapter作为收听者附加,并覆盖mouseExit()方法。
答案 1 :(得分:0)
作为另一种选择,您可以使用AbstractHoverInformationControlManager
中的org.eclipse.jface.text
来处理所有令人讨厌的细节(例如,当您将Alt + Tab移出应用程序时,您的工具提示会消失吗?)。事件处理得到了处理,您可以专注于有趣的事情。一个例子:
import org.eclipse.jface.text.AbstractHoverInformationControlManager;
import org.eclipse.jface.text.AbstractReusableInformationControlCreator;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class Example {
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
shell.setSize(200, 200);
final ExampleHoverInformationControlManager controlManager = new ExampleHoverInformationControlManager();
// This must be done for the control for which you want the mouse
// tracking to be enabled and you possibly want to show hovers.
controlManager.install(shell);
shell.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
controlManager.dispose();
}
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
private static class ExampleHoverInformationControlCreator extends
AbstractReusableInformationControlCreator {
@Override
protected IInformationControl doCreateInformationControl(Shell parent) {
return new DefaultInformationControl(parent);
}
}
private static class ExampleHoverInformationControlManager extends
AbstractHoverInformationControlManager {
protected ExampleHoverInformationControlManager() {
super(new ExampleHoverInformationControlCreator());
}
@Override
protected void computeInformation() {
MouseEvent e = getHoverEvent();
// Just a static example area for simplicity
if (e.x >= 0 && e.x < 100 && e.y >= 0 && e.y < 20) {
Rectangle area = new Rectangle(0, 0, 100, 20);
setInformation(
"This can be a string or something else, you control it", area); //$NON-NLS-1$
return;
}
// computeInformation must setInformation in all cases
setInformation(null, null);
}
}
}
答案 2 :(得分:0)
我刚刚发现了一个更好的解决方案。它就像这样运行。
Shell coverup = new Shell(SWT.NO_TRIM) ;
coverup.setBounds(parentComposite.getShell().getBounds());
coverup.moveAbove( Display.getCurrent().getActiveShell() );
coverup.setAlpha( 13 );
coverup.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
popupShell = new Shell( coverup, SWT.NO_TRIM );
coverup.addMouseMoveListener(new MouseMoveListener() {
@Override
public void mouseMove( MouseEvent mouseEvent )
{
System.out.println( "coverup - mouse moves" );
coverup.close() ;
}
});
用英语表示:
创建一个与应用程序/父shell相同大小的不可见shell。
用不可见的shell覆盖父shell。
附加鼠标将侦听器连接到覆盖外壳。
创建实际弹出窗口作为覆盖shell的子级,并在其上方 当鼠标进入弹出窗口时,激活掩盖。
这意味着无论鼠标在弹出窗口后的哪个位置,它都会进入封面外壳 - 而封面鼠标输入事件会处理所有内容。
我们没有检测到鼠标何时退出弹出窗口 - 我们正在检测鼠标何时进入周围环境。
添加了奖励:将掩盖的背景设置为浅灰色,低Alpha设置使得整个应用程序巧妙地“变灰” - 因此用户知道已被禁用。
小问题:如果弹出式shell没有完全包含在应用程序窗口中,弹出式shell会在应用程序窗口之外,鼠标可以在不触发覆盖shell的情况下进行转义。
除此之外 - 这非常有效!