在Vaadin中将弹出窗口水平居中

在Vaadin中将弹出窗口水平居中,vaadin,vaadin7,Vaadin,Vaadin7,我在我的主UI中添加了一个弹出窗口,如下所示: Window component = new Window(); UI.getCurrent().addWindow(component); 现在,我希望弹出窗口水平居中,例如距屏幕顶部40像素。据我所知,瓦丁有4种方法来定位我的窗口 component.center() component.setPosition(x, y) component.setPositionX(x) component.setPositionY(y) 这些都不是我真

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

Window component = new Window();
UI.getCurrent().addWindow(component);
现在,我希望弹出窗口水平居中,例如距屏幕顶部40像素。据我所知,瓦丁有4种方法来定位我的窗口

component.center()
component.setPosition(x, y)
component.setPositionX(x)
component.setPositionY(y)
这些都不是我真正想要的。起初我希望塞蒂能帮助我。这确实允许我从顶部获得正确的距离,但x位置现在设置为0,我希望它位于中心位置

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

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

您知道如何正确定位窗口组件吗?

解决方案1:使用 实际上,
setPositionY()
会将窗口的
居中属性重置为
false
。由于弹出窗口和浏览器窗口的宽度在显示在屏幕上之前是未知的,因此我知道获取这些值的唯一方法是使用SizerReporter附加组件。它的使用非常简单:

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,但我个人尽可能避免使用CSS(使用Vaadin:)

在添加附加组件作为依赖项后,需要重新编译widgetset

解决方案2:使用 我不会保证这个解决方案的可移植性,但我想它会在大多数现代浏览器上工作

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)");
    }
}

为此,我使用了
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)
);

我删除了我的答案,因为它是错的。问题似乎是,
center()
是在客户端执行的。你知道弹出窗口的宽度吗?(通常你必须定义宽度)不,我不知道弹出窗口的宽度,它取决于内容。正如我提到的,组件上的getWidth方法没有多大帮助,因为它只返回100%。不幸的是,我正在处理的项目不太喜欢使用各种附加组件,尤其是对于这样一个小东西。我也尝试过使用CSS,但没有任何运气。看来我唯一的选择可能是制作自己的定制组件……不用担心,我完全理解,这种东西应该内置到Vaadin中。也许你可以在那里开一张票(dev.vaadin.com)。不过,我相信我已经找到了另一个解决方案,我会在稍后发布它…谢谢,我会接受你的回答。我只希望该功能可以直接在Vaadin中实现:-)