加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

如何在窗口外单击鼠标关闭Vaadin子窗口?

发布时间:2020-12-14 02:54:41 所属栏目:Windows 来源:网络整理
导读:我正在使用vaadin 7,在我的应用程序中,我有时会使用子窗口.在一个案例中,我有一个模态窗口,里面有几个组件.单击模态窗口内的某些组件时,它会打开另一个窗口.当用户点击它时,我希望此窗口自动关闭(例如,再次在模态窗口上).在 Vaadin Sampler中,这种行为似乎在
我正在使用vaadin 7,在我的应用程序中,我有时会使用子窗口.在一个案例中,我有一个模态窗口,里面有几个组件.单击模态窗口内的某些组件时,它会打开另一个窗口.当用户点击它时,我希望此窗口自动关闭(例如,再次在模态窗口上).在 Vaadin Sampler中,这种行为似乎在显示源时实现(单击右上角的源按钮).如果不是从模态窗口打开,则行为应该相同,但是从UI或任何其他子窗口打开.

我尝试了几件事:

>使用Popupview是不可能的,因为我需要从组件(按钮或图像)打开窗口
>将BlurListener添加到新窗口不起作用,因为如果我在窗口内单击,则会触发blurevent(例如移动窗口)
>将ClickListener添加到UI没有帮助,因为单击模态窗口时未触发事件.

实现这一目标的正确方法是什么?

谢谢
拉斐尔

解决方法

我有同样的问题,对任何答案都不满意:

> @Steven Spungin提出的聚焦/模糊方法确实有效,但前提是窗口内没有其他可聚焦元素.否则单击其中一个元素将关闭窗口,这是非常不需要的.
> @Steven Spungin使用“玻璃元素”为他的第一个答案提出了一个解决方案,但它仅适用于模态窗口,并且通常不是很灵活.
>回答@dwi wahyu utomo,他建议用UI.getCurrent()添加点击监听器.addClickListener并检查点击事件坐标是否在一个窗口内工作,但它有一个主要问题:点击事件是“消耗的” “由Vaadin提供并且不会传播到浏览器.这意味着点击页面上的任何位置都不会导致正常行为,例如右键单击不会显示本机上下文菜单.

我想到了一个基于客户端连接器创建简单AbstractExtension的想法,该连接器扩展了特定组件并监听页面上的所有点击事件.如果单击的目标不在扩展组件内,则通知服务器端连接器.

这是客户端连接器:

@Connect(ClickOutsideComponentExtension.class)
public class ClickOutsideComponentConnector extends AbstractExtensionConnector implements NativePreviewHandler {

    private ComponentConnector extendedConnector;
    private ClickOutsideComponentRpc rpc;
    private HandlerRegistration handlerRegistration;

    @Override
    protected void extend(ServerConnector target) {
        extendedConnector = (ComponentConnector) target;
        rpc = getRpcProxy(ClickOutsideComponentRpc.class);
        handlerRegistration = Event.addNativePreviewHandler(this);
    }

    @Override
    public void onUnregister() {
        super.onUnregister();
        handlerRegistration.removeHandler();
    }

    @Override
    public void onPreviewNativeEvent(NativePreviewEvent event) {
        if (extendedConnector.isEnabled()) {
            Element eventTarget = Element.as(event.getNativeEvent().getEventTarget());
            if (Event.ONCLICK == event.getTypeInt() && !isElementInsideExtendedElement(eventTarget)) {
                rpc.onClickOutside();
            }
        }
    }

    public boolean isElementInsideExtendedElement(Element element) {
        Element outsideElement = extendedConnector.getWidget().getElement();
        Element insideElement = element;

        while (insideElement != null) {
            if (outsideElement.equals(insideElement)) {
                return true;
            }
            insideElement = insideElement.getParentElement();
        }
        return false;
    }

}

RPC用于客户端和服务器端之间的通信:

public interface ClickOutsideComponentRpc extends ServerRpc {
    void onClickOutside();
}

和服务器端扩展:

public class ClickOutsideComponentExtension extends AbstractExtension {

    private List<ClickOutsideListener> clickOutsideListeners = new ArrayList<>();

    public interface ClickOutsideListener extends Serializable {
        void onClickOutside();
    }

    @Override
    public void extend(AbstractClientConnector target) {
        super.extend(target);
        registerRpc(new ClickOutsideComponentRpc() {


            @Override
            public void onClickOutside() {
                for (ClickOutsideListener listener : clickOutsideListeners) {
                    if (listener != null) {
                        listener.onClickOutside();
                    }
                }
            }
        });
    }

    public void addClickOutsideListener(ClickOutsideListener listener) {
        clickOutsideListeners.add(listener);
    }
}

如前所述,此解决方案适用于任何组件之外的点击,因此您可以执行以下操作:

Label label = new Label("Try to click outside!");
ClickOutsideComponentExtension ext = new ClickOutsideComponentExtension();
ext.extend(label);
ext.addClickOutsideListener(new ClickOutsideListener() {

    @Override
    public void onClickOutside() {
        Notification.show("Click outside of label");
    }
});
addComponent(label);

或点击窗外点击窗口:

Button btn = new Button("Open window");
btn.addClickListener(new ClickListener() {

    @Override
    public void buttonClick(ClickEvent event) {
        Window w = new Window();
        w.setContent(new Button("Focusable button"));
        w.center();
        ClickOutsideComponentExtension ext = new ClickOutsideComponentExtension();
        ext.extend(w);
        ext.addClickOutsideListener(new ClickOutsideListener() {

            @Override
            public void onClickOutside() {
                w.close();
            }
        });
        UI.getCurrent().addWindow(w);
    }
});
addComponent(btn);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读