在Vaadin中水平居中弹出窗口

时间:2016-04-15 08:26:12

标签: vaadin vaadin7

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

HashSet

现在,我想让我的弹出窗口水平居中,例如距离屏幕顶部40个像素。据我所知,Vaadin有四种定位窗口的方法。

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

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

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

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

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

2 个答案:

答案 0 :(得分:2)

我使用了来自getBrowserWindowWidth()类的方法getBrowserWindowHeight()com.vaadin.server.Page

我将“日志”窗口水平放在浏览器窗口的下半部分

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

答案 1 :(得分:1)

解决方案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)");
    }
}