gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 17:22:15 27 4
gpt4 key购买 nike

我正在使用 vaadin 7,有时在我的应用程序中我使用子窗口。在一种情况下,我有一个包含多个组件的模式窗口。单击模式窗口内的某些组件时,它会打开另一个窗口。我希望这个窗口在用户点击它外部时自动关闭(例如再次在模态窗口上)。在 Vaadin Sampler显示源时似乎实现了此行为(单击右上角的源按钮)。如果不是从模式窗口打开,而是从 UI 或任何其他子窗口打开,行为也应该相同。

我尝试了几件事:

  • 无法使用 Popupview,因为我需要从组件(按钮或图像)打开窗口
  • 向新窗口添加 BlurListener 不起作用,因为如果我在窗口内单击,会触发模糊事件(例如移动窗口)
  • 向 UI 添加 ClickListener 没有帮助,因为单击模式窗口时未触发事件。

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

    谢谢
    拉斐尔

    最佳答案

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

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

  • 我的想法是创建一个简单的 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);

    关于window - 如何在窗口外单击鼠标关闭 Vaadin 子窗口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20326548/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com