Close the SWT shell by clicking on it.

I have a JFace dialog:

setShellStyle(SWT.APPLICATION_MODAL | SWT.CLOSE);
setBlockOnOpen(false);

Is there a way to close it by clicking somewhere outside the dialog box? Perhaps something like listening to a click event on a full screen and detecting it outside its dialog box and then closing it.

+4
source share
2 answers

You can attach the listener SWT.Deactivateto the basic Shelldialog.

To connect a listener, you can override this Window::configureShellas follows:

@Override
protected void configureShell(Shell shell) {
  super.configureShell(shell);
  shell.addListener(SWT.Deactivate, event -> shell.close());
}

Here is a separate SWT example to illustrate a bare mechanism:

Display display = new Display();
Shell parentShell = new Shell(display);
parentShell.setSize(500, 500);
parentShell.open();
Shell shell = new Shell(parentShell);
shell.addListener(SWT.Deactivate, event -> shell.close());
shell.setSize(300, 300);
shell.setText("Closes on Deactivate");
shell.open();
while (!parentShell.isDisposed()) {
  if (!display.readAndDispatch())
    display.sleep();
}
display.dispose();
+2
source

Dialog , , Shell MouseEvent, Dialog .

, JNativeHook . , , , .

:

GlobalScreen.addNativeMouseListener(new NativeMouseInputAdapter() {
    public void nativeMouseClicked(final NativeMouseEvent nativeMouseEvent) {
        display.syncExec(new Runnable() {
            public void run() {
                if (dialog.getShell() == null || dialog.getShell().isDisposed()) {
                    return;
                }
                // Close the dialog if there is a mouse click outside the bounds of the dialog
                if (!dialog.getShell().getBounds().contains(awtToSwtPoint(nativeMouseEvent.getPoint()))) {
                    dialog.close();
                }
            }
        });
    }
});

, , /- .


:

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.mouse.NativeMouseEvent;
import org.jnativehook.mouse.NativeMouseInputAdapter;

public class DialogCloseTest {

    private final Display display;
    private final Shell shell;

    public DialogCloseTest() {
        display = new Display();
        shell = new Shell(display);
        shell.setSize(450, 450);

        final Dialog dialog = new MyDialog(shell);
        dialog.open();

        registerNativeHook();

        GlobalScreen.addNativeMouseListener(new NativeMouseInputAdapter() {
            public void nativeMouseClicked(final NativeMouseEvent nativeMouseEvent) {
                display.syncExec(new Runnable() {
                    public void run() {
                        if (dialog.getShell() == null || dialog.getShell().isDisposed()) {
                            return;
                        }
                        // Close the dialog if there is a mouse click outside the bounds of the dialog
                        if (!dialog.getShell().getBounds().contains(awtToSwtPoint(nativeMouseEvent.getPoint()))) {
                            dialog.close();
                        }
                    }
                });
            }
        });
    }

    private org.eclipse.swt.graphics.Point awtToSwtPoint(final java.awt.Point point) {
        return new org.eclipse.swt.graphics.Point(point.x, point.y);
    }

    private static void registerNativeHook() {
        try {
            GlobalScreen.registerNativeHook();
        } catch (NativeHookException ex) {
            System.err.println("There was a problem registering the native hook.");
            System.err.println(ex.getMessage());
            System.exit(1);
        }
    }

    private static void unregisterNativeHook() {
        try {
            GlobalScreen.unregisterNativeHook();
        } catch (NativeHookException e) {
            System.err.println("There was a problem unregistering the native hook.");
            System.err.println(e.getMessage());
        }
    }

    private static class MyDialog extends Dialog {

        MyDialog(final Shell parent) {
            super(parent);
        }

        @Override
        protected void configureShell(final Shell shell) {
            super.configureShell(shell);
            setShellStyle(SWT.APPLICATION_MODAL | SWT.CLOSE);
            setBlockOnOpen(false);
        }    

    }

    public void run() {
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        display.dispose();
        unregisterNativeHook();
    }

    public static void main(String... args) {
        new DialogCloseTest().run();
    }

}

. Dialog, (, alt-tab), , , , )

0

Source: https://habr.com/ru/post/1692769/


All Articles