在 Vaadin 中水平居中弹出 window
Horizontally centering a popup window in Vaadin
我已经在我的主 UI 中添加了一个弹出窗口 window,如下所示:
Window component = new Window();
UI.getCurrent().addWindow(component);
现在,我希望弹出窗口水平居中,例如距屏幕顶部 40 像素。据我所知,Vaadin 有 4 种方法来定位我的 window.
component.center()
component.setPosition(x, y)
component.setPositionX(x)
component.setPositionY(y)
None这几个才是我真正想要的。起初我希望 setPositionY 可以帮助我。这确实允许我获得与顶部的正确距离,但 x 位置现在设置为 0,我希望它居中。
如果我能够计算出 x 位置应该是什么,setPosition 可能会有所帮助,但这需要我知道组件的宽度(以像素为单位),但 component.getWidth 只告诉我 100% .
接下来我尝试在组件上使用 CSS 样式,编写明确的 css 规则并使用 addStyleName 将其添加到组件中。似乎 Vaadin 用自己的默认值覆盖了我在 css 中写的任何内容...
关于如何正确定位我的 Window 组件有什么想法吗?
解决方案 1:使用 SizeReporter
确实,setPositionY()
会将 window 的 centered
属性 重置为 false
。由于弹出窗口的宽度和浏览器 window 的宽度在出现在屏幕上之前是未知的,所以我知道获取这些值的唯一方法是使用 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 glitches",因为在您调整大小时,加载项几乎不断地发送调整大小事件弹出...
您可以尝试使用 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)");
}
}
为此,我使用了 com.vaadin.server.Page
class 中的方法 getBrowserWindowWidth()
和 getBrowserWindowHeight()
。
我将 "log" window 水平居中在浏览器的下部 window 和
myWindow.setHeight("30%");
myWindow.setWidth("96%");
myWindow.setPosition(
(int) (Page.getCurrent().getBrowserWindowWidth() * 0.02),
(int) (Page.getCurrent().getBrowserWindowHeight() * 0.65)
);
我已经在我的主 UI 中添加了一个弹出窗口 window,如下所示:
Window component = new Window();
UI.getCurrent().addWindow(component);
现在,我希望弹出窗口水平居中,例如距屏幕顶部 40 像素。据我所知,Vaadin 有 4 种方法来定位我的 window.
component.center()
component.setPosition(x, y)
component.setPositionX(x)
component.setPositionY(y)
None这几个才是我真正想要的。起初我希望 setPositionY 可以帮助我。这确实允许我获得与顶部的正确距离,但 x 位置现在设置为 0,我希望它居中。
如果我能够计算出 x 位置应该是什么,setPosition 可能会有所帮助,但这需要我知道组件的宽度(以像素为单位),但 component.getWidth 只告诉我 100% .
接下来我尝试在组件上使用 CSS 样式,编写明确的 css 规则并使用 addStyleName 将其添加到组件中。似乎 Vaadin 用自己的默认值覆盖了我在 css 中写的任何内容...
关于如何正确定位我的 Window 组件有什么想法吗?
解决方案 1:使用 SizeReporter
确实,setPositionY()
会将 window 的 centered
属性 重置为 false
。由于弹出窗口的宽度和浏览器 window 的宽度在出现在屏幕上之前是未知的,所以我知道获取这些值的唯一方法是使用 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 glitches",因为在您调整大小时,加载项几乎不断地发送调整大小事件弹出...
您可以尝试使用 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)");
}
}
为此,我使用了 com.vaadin.server.Page
class 中的方法 getBrowserWindowWidth()
和 getBrowserWindowHeight()
。
我将 "log" window 水平居中在浏览器的下部 window 和
myWindow.setHeight("30%");
myWindow.setWidth("96%");
myWindow.setPosition(
(int) (Page.getCurrent().getBrowserWindowWidth() * 0.02),
(int) (Page.getCurrent().getBrowserWindowHeight() * 0.65)
);