Утилизировать оболочку SWT, когда курсор выходит из нее - PullRequest
0 голосов
/ 11 марта 2010

Я реализую пользовательский предварительный просмотр / всплывающую подсказку для плагина Eclipse. Это было сделано с помощью Shell в SWT, удалив все его обрезки и поместив в него текстовое поле. Это выглядит здорово. Однако теперь мне нужно избавиться от оболочки, когда курсор выходит из окна оболочки, и я столкнулся с некоторыми проблемами:

Имеет ли смысл подключать mousemoveListener к оболочке? Сначала я делал это, но потом понял, что этот слушатель захватывает только события перемещения мыши, которые происходят внутри оболочки. Как я поймаю мышь, выходящую из раковины, чтобы я мог избавиться от нее?

Спасибо и всего наилучшего, Krt_Malta

Ответы [ 3 ]

2 голосов
/ 11 марта 2010

Присоедините MouseTrackListener с MouseTrackAdapter в качестве прослушивателя и переопределите mouseExit () метод.

0 голосов
/ 24 октября 2012

Я только что обнаружил гораздо лучшее решение. Это работает так.

                            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() ;
                    }
            });

Что по-английски:

Создайте невидимую оболочку того же размера, что и оболочка приложения / родителя.

Накройте родительскую оболочку невидимой оболочкой.

Прикрепите мышь. Введите слушателя к покрывающей оболочке.

Создайте фактическое всплывающее окно как дочерний элемент покрывающей оболочки и поверх нее Когда мышь входит во всплывающее окно, активируйте прикрытие.

Это означает, что независимо от того, куда мышь попадает после появления всплывающего окна, она попадает в оболочку сокрытия - и событие ввода мыши сокрытия удаляет все.

Мы не определяем, когда мышь выходит из всплывающего окна, мы определяем, когда мышь входит в окружение.

Дополнительный бонус: установка фона прикрытия на светло-серый и низкий альфа-канал делает все приложение слегка «серым», поэтому пользователь знает, что он отключен.

Небольшая ошибка: если всплывающая оболочка не полностью содержится в окне приложения, где всплывающая оболочка выходит за пределы окна приложения, мышь может выйти без запуска оболочки прикрытия.

Кроме этого - это работает очень хорошо!

0 голосов
/ 31 мая 2012

В качестве другого варианта вы можете использовать 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);
        }
    }
}
...