【问题标题】:Horizontally centering a popup window in Vaadin在 Vaadin 中水平居中弹出窗口
【发布时间】:2016-04-15 08:26:12
【问题描述】:

我在主 UI 中添加了一个弹出窗口,如下所示:

Window component = new Window();
UI.getCurrent().addWindow(component);

现在,我希望我的弹出窗口水平居中,例如距屏幕顶部 40 像素。据我所知,Vaadin 有 4 种方法来定位我的窗口。

component.center()
component.setPosition(x, y)
component.setPositionX(x)
component.setPositionY(y)

这些都不是我真正想要的。起初我希望 setPositionY 可以帮助我。这确实让我可以从顶部获得正确的距离,但是 x 位置现在设置为 0,我希望它居中。

如果我能够计算 x 位置应该是什么,setPosition 可能会有所帮助,但这需要我知道组件的宽度(以像素为单位),但 component.getWidth 只告诉我 100%。

接下来我尝试在组件上使用 CSS 样式,编写和显式的 css 规则并使用 addStyleName 将其添加到组件中。似乎 Vaadin 用自己的默认值覆盖了我在 CSS 中编写的任何内容......

知道如何正确定位我的 Window 组件吗?

【问题讨论】:

  • 我删除了我的答案,因为它是错误的。事情似乎是,center() 在客户端执行。你知道弹出窗口的宽度吗? (通常你必须定义宽度)
  • 不,我不知道弹出窗口的宽度,它取决于内容。正如我提到的,组件上的 getWidth 方法没有多大帮助,因为它只是返回 100 %。

标签: vaadin vaadin7


【解决方案1】:

为此,我使用了 com.vaadin.server.Page 类中的 getBrowserWindowWidth()getBrowserWindowHeight() 方法。

我将我的“日志”窗口水平居中于浏览器窗口的下半部分

myWindow.setHeight("30%");
myWindow.setWidth("96%");
myWindow.setPosition(
    (int) (Page.getCurrent().getBrowserWindowWidth() * 0.02),
    (int) (Page.getCurrent().getBrowserWindowHeight() * 0.65)
);

【讨论】:

    【解决方案2】:

    解决方案 1:使用SizeReporter

    确实,setPositionY() 会将窗口的centered 属性重置为false。由于弹出窗口的宽度和浏览器窗口的宽度在它们出现在屏幕上之前是未知的,因此我知道获取这些值的唯一方法是使用 SizeReporter 插件。它的使用非常简单:

    public class MyUI extends UI {
    
        private Window popUp;
    
        private SizeReporter popUpSizeReporter;
        private SizeReporter windowSizeReporter;
    
        @Override
        protected void init(VaadinRequest request) {
    
            Button button = new Button("Content button");
            VerticalLayout layout = new VerticalLayout(button);
            layout.setMargin(true);
    
            popUp = new Window("Pop-up", layout);
            popUp.setPositionY(40);
    
            addWindow(popUp);
    
            popUpSizeReporter = new SizeReporter(popUp);
            popUpSizeReporter.addResizeListenerOnce(this::centerPopUp);
    
            windowSizeReporter = new SizeReporter(this);
            windowSizeReporter.addResizeListenerOnce(this::centerPopUp);
        }
    
        private void centerPopUp(ComponentResizeEvent event) {
    
            int popUpWidth = popUpSizeReporter.getWidth();
            int windowWidth = windowSizeReporter.getWidth();
    
            if (popUpWidth == -1 || windowWidth == -1) {
                return;
            }
    
            popUp.setPositionX((windowWidth - popUpWidth) / 2);
        }
    }
    

    只要不调整弹出窗口的大小,这段代码就可以了。如果这样做,它将不会自动重新定位。如果您将addResizeListenerOnce() 替换为addResizeListener(),那么它将自动重新定位弹出窗口,但您会遇到一些“UI 故障”,因为在您调整弹出窗口大小时,插件几乎会不断发送调整大小事件。 .

    您可以尝试使用 CSS,但我个人尽可能避免使用 Vaadin 的 CSS :)。

    将插件添加为依赖项后,您需要重新编译小部件集。

    解决方案 2:使用com.vaadin.ui.JavaScript

    我不保证此解决方案的可移植性,但我想它适用于大多数现代浏览器。

    public class MyUI extends UI {
    
        private Window popUp;
    
        @Override
        protected void init(VaadinRequest request) {
    
            Button button = new Button("Content button");
            VerticalLayout layout = new VerticalLayout(button);
            layout.setMargin(true);
    
            popUp = new Window("Pop-up", layout);
            popUp.setPositionY(40);
            popUp.addStyleName("window-center");
    
            addWindow(popUp);
    
            // Add a JS function that can be called from the client.
            JavaScript.getCurrent().addFunction("centerWindow", args -> {
                popUp.setPositionX((int) ((args.getNumber(1) - args.getNumber(0)) / 2));
            });
    
            // Execute the function now. In real code you might want to execute the function just after the window is displayed, probably in your enter() method.
            JavaScript.getCurrent().execute("centerWindow(document.getElementsByClassName('window-center')[0].offsetWidth, window.innerWidth)");
        }
    }
    

    【讨论】:

    • 不幸的是,我正在做的项目不太喜欢使用各种附加组件,尤其是对于这么小的东西。我也尝试过使用 CSS,但没有任何运气。看来我唯一的选择可能是制作自己的自定义组件...
    • 不用担心,我完全理解,这种东西应该内置在 Vaadin 中。也许你可以在那里开一张票(dev.vaadin.com)。不过,我相信我已经找到了另一种解决方案,我会在稍后发布它......
    • 谢谢,我会接受你的回答。我只是希望该功能可以直接在 Vaadin 中实现 :-)
    猜你喜欢
    • 2016-05-10
    • 1970-01-01
    • 1970-01-01
    • 2015-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-09
    • 2011-05-03
    相关资源
    最近更新 更多