1

我正在寻找用我的软件模拟窗口拖动。我目前有一些画布,它们在视图中就像它自己的窗口一样。我在它们之间创建了一个拖放,这一切都非常可靠。但是,当我拖放到死区时,我希望做一个拖动案例。或者更好地表述为我的应用程序未涵盖的区域。我的第一个想法是听鼠标移动到当前外壳之外,然后做一些事情。但是,我似乎无法找到一种方法来检测我在外壳之外。

任何帮助将不胜感激。

4

1 回答 1

0

我似乎无法找到一种方法来检测我在外壳之外。

如果您使用的是MouseListener,则可以实现mouseUp(MouseEvent)方法并通过MouseEvent对象获取鼠标释放的点。

@Override
public void mouseUp(final MouseEvent event) {
    final Point releasePoint = new Point(e.x, e.y);
}

请注意,此位置将相对于添加此侦听器的对象的父 Shell。您需要将该父 Shell 的位置添加到上面的 (x,y) 对中,以获得屏幕上的绝对位置。

现在您有了单击某个目标对象后释放鼠标的点,您可以使用Rectangle.contains(Point)方法检查该点是否在原始窗口之外。

final Composite target = new Composite(parentComposite, SWT.NONE);
target.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseUp(final MouseEvent event) {
        final Point releasePoint = new Point(event.x + target.getShell().getLocation().x,
                                             event.y + target.getShell().getLocation().y);
        if (!target.getShell().contains(releasePoint)) {
            // Dragged and dropped outside the window!
        }
    }
});

从这里你可以做任何你需要做的工作来创建一个新的 shell 并将目标移动到那个 shell。


这是我放在一起的一个小工作示例,您可以在其中将黄色矩形拖放到一个窗口中,它将创建一个包含矩形的新窗口:

public static void main(final String... args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setText("Original shell");
    shell.setLayout(new FillLayout());
    shell.setMaximized(true);

    final Composite parentComposite = new Composite(shell, SWT.NONE);
    parentComposite.setLayout(new GridLayout());
    parentComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

    final Composite target = new Composite(parentComposite, SWT.NONE);
    target.setBounds(new Rectangle(0, 0, 100, 100));
    target.setBackground(new Color(display, 255, 255, 0));
    target.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseUp(final MouseEvent event) {
            final Point releasePoint = new Point(event.x + target.getShell().getLocation().x,
                                                 event.y + target.getShell().getLocation().y);
            if (!target.getShell().getBounds().contains(releasePoint)) {
                // Create the new shell and base composite
                final Shell newShell = new Shell(display);
                newShell.setText("New shell");
                newShell.setLayout(new FillLayout());
                newShell.setMaximized(true);
                final Composite newComposite = new Composite(newShell, SWT.NONE);
                newComposite.setLayout(new GridLayout());
                newComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

                // Set the parent of the target widget to the new base composite
                target.setParent(newComposite);
                target.layout();

                // Open the new shell
                newShell.setLocation(releasePoint);
                newShell.setSize(300, 300);
                newShell.open();
            }
        }
    });

    shell.setSize(300, 300);
    shell.open();
    display.readAndDispatch();

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

编辑:只是为了澄清,如果您使用 Canvas (您在问题中提到)而不是 Composite 作为target对象,它的行为将完全相同。

于 2016-08-01T16:48:46.703 回答