Shell 当光标移出SWT外壳时,处理SWT外壳

Shell 当光标移出SWT外壳时,处理SWT外壳,shell,swt,tooltip,dispose,Shell,Swt,Tooltip,Dispose,我正在为Eclipse插件实现一个自定义预览/工具提示。它在SWT中使用了一个外壳,去掉了所有的装饰并在里面放了一个文本框。看起来很棒。但是,现在当光标移出shell窗口时,我需要处理shell,并遇到一些问题: 将mousemoveListener附加到外壳上有意义吗?首先我这样做了,但后来我意识到这个监听器只捕获shell中发生的鼠标移动事件。我将如何捕捉出壳的老鼠,以便处理它 感谢和问候, Krt_Malta附加一个with作为侦听器和重写方法。作为另一个选项,您可以使用org.eclip

我正在为Eclipse插件实现一个自定义预览/工具提示。它在SWT中使用了一个外壳,去掉了所有的装饰并在里面放了一个文本框。看起来很棒。但是,现在当光标移出shell窗口时,我需要处理shell,并遇到一些问题:

将mousemoveListener附加到外壳上有意义吗?首先我这样做了,但后来我意识到这个监听器只捕获shell中发生的鼠标移动事件。我将如何捕捉出壳的老鼠,以便处理它

感谢和问候,
Krt_Malta

附加一个with作为侦听器和重写方法。

作为另一个选项,您可以使用
org.eclipse.jface.text
中的
AbstractHoverInformationControlManager
,它处理所有令人讨厌的细节(例如,当您将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);
        }
    }
}
import org.eclipse.jface.text.AbstractHoverInformationControlManager;
导入org.eclipse.jface.text.AbstractReusableInformationControlCreator;
导入org.eclipse.jface.text.DefaultInformationControl;
导入org.eclipse.jface.text.iInformation控件;
导入org.eclipse.swt.events.DisposeEvent;
导入org.eclipse.swt.events.dispelistener;
导入org.eclipse.swt.events.MouseEvent;
导入org.eclipse.swt.graphics.Rectangle;
导入org.eclipse.swt.layout.FillLayout;
导入org.eclipse.swt.widgets.Display;
导入org.eclipse.swt.widgets.Shell;
公开课范例{
公共静态void main(字符串[]args){
最终显示=新显示();
最终外壳=新外壳(显示);
setLayout(新的FillLayout());
外壳。设置尺寸(200200);
最终示例HoverInformationControlManager控制管理器=新示例HoverInformationControlManager();
//必须为要使用鼠标的控件执行此操作
//要启用跟踪,可能需要显示悬停。
安装(shell);
shell.addDisposeListener(新DisposeListener(){
公共无效widgetDisposed(处置事件e){
controlManager.dispose();
}
});
shell.open();
而(!shell.isDisposed()){
如果(!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
私有静态类示例HoverInformationControlCreator扩展
AbstractReusableInformationControlCreator{
@凌驾
受保护的IIInformationControl doCreateInformationControl(外壳程序父级){
返回新的DefaultInformationControl(父级);
}
}
私有静态类示例HoverInformationControlManager扩展
抽象信息控制管理器{
受保护的示例HoverInformationControlManager(){
super(新示例hoverinformationcontrolcreator());
}
@凌驾
受保护的无效计算信息(){
MouseEvent e=getHoverEvent();
//为了简单起见,这只是一个静态示例区域
如果(e.x>=0&&e.x<100&&e.y>=0&&e.y<20){
矩形区域=新矩形(0,0,100,20);
设置信息(
“这可以是字符串或其他东西,由您控制”,区域);//$NON-NLS-1$
返回;
}
//computeInformation必须在所有情况下设置信息
设置信息(null,null);
}
}
}

我刚刚发现了一个更好的解决方案。它是这样运行的

                            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() ;
                    }
            });
其中英文为:

创建与应用程序/父外壳大小相同的不可见外壳

用不可见的壳覆盖父壳

将鼠标输入侦听器连接到外壳

将实际弹出窗口创建为覆盖壳的子对象,并位于覆盖壳的顶部 当鼠标进入弹出窗口时,激活掩盖

这意味着,无论鼠标进入弹出窗口后走到哪里,它都会进入coverup外壳,coverup鼠标进入事件会处理所有内容

我们不是在检测鼠标何时退出弹出窗口,而是在检测鼠标何时进入周围环境

额外的好处:将coverup的背景设置为浅灰色和低Alpha,会使整个应用程序微妙地“变灰”——因此用户知道它已被禁用

小问题:如果弹出外壳没有完全包含在appwindow中,当弹出外壳位于appwindow之外时,鼠标可以在不触发掩盖外壳的情况下逃逸


除此之外,这真的很好用

谢谢,太棒了,它成功了!现在有一个技术问题:严格地说,我将侦听器附加到shell中的文本框,而不是shell,因为我不知道某些原因,所以没有为shell生成事件。因此,当我移动到文本框右侧的滚动条时,由于鼠标已移出文本框,所以外壳被释放。如何将侦听器连接到shell?感谢和问候,Krt_MaltaYou可以直接将其连接到shell,shell也是一个小部件。