我正在使用Vaadin 8.5.1和Vaading Desiin与Spring Boot 2.0.4的组合。
目前我正在尝试在页面底部添加一个PopupView,它会在按钮单击时打开。在Popup中有一个垂直布局,包括两个组件:HorizontalSplitPanel和Button。 PopupView应该具有当前BrowserWindow的宽度和高度的三分之一。 HorizontalSplitPanel应该使用弹出窗口中的所有空间,按钮不需要该空间。
我做了什么:
@SpringComponent
@UIScope
public class View extends VerticalLayout implements Observer {
private final PopupContentView popupContentView;
private PopupView popup;
@Autowired
public View(PopupContentView popupContentView) {
this.popupContentView = popupContentView;
}
@PostConstruct
void init() {
button.addClickListener(clickEvent -> openPopup());
}
private void openPopup() {
if (popup == null) {
setSizeOfPopUp();
// popup will adjust automatically to size of content
popup = new PopupView(null, popupContentView);
popup.addPopupVisibilityListener(event -> {
if (event.isPopupVisible()) {
popupContentView.build(this::submitted);
}
});
popup.setHideOnMouseOut(false);
this.addComponent(popup);
}
popup.setPopupVisible(true);
}
private void setSizeOfPopUp() {
if (popupContentView != null) {
popupContentView.setWidth(Page.getCurrent().getBrowserWindowWidth(), Unit.PIXELS);
popupContentView.setHeight(((float) Page.getCurrent().getBrowserWindowHeight()) / 3, Unit.PIXELS);
}
}
private void submitted() {
// do some stuff
}
@Override
public void update(Observable observable, Object o) {
if (observable instanceof BrowserWindowResizeListenerObservable) {
setSizeOfPopUp();
}
}
}
@Service
public class BrowserWindowResizeListenerObservable extends Observable implements Page.BrowserWindowResizeListener {
@Override
public void browserWindowResized(Page.BrowserWindowResizeEvent browserWindowResizeEvent) {
this.setChanged();
this.notifyObservers();
}
}
@SpringComponent
@UIScope
public class PopupContentView extends VerticalLayout {
private SubmitCallback submitCallback;
private Button submitBtn;
@PostConstruct
void init() {
super.init();
}
void build(@NotNull SubmitCallback) {
removeAllComponents();
this.addComponent(horizontalSplitPanel);
this.addComponent(submitBtn);
this.setExpandRatio(horizontalSplitPanel, 1.0f);
this.submitCallback = callback;
}
private void submit() {
submitCallback.submit(someContent);
}
@FunctionalInterface
public interface SubmitCallback {
void submit(SomeContent someContent);
}
}
如您所见,我有一个主视图,一个内容视图和一个监听器类。我想要发生的是弹出窗口在按钮点击时可见,并包含面板和提交按钮的内容视图。面板占据了剩余的空间,按钮不需要。弹出窗口充满了内容。
实际发生的是面板占用弹出窗口的完整空间,按钮将显示在弹出窗口下方。但是,当我调整窗口大小并调整大小事件时,一切都很好,按钮不再位于弹出窗口下方。似乎填充和边距(这是Vaadin中扩展比率的HTML实现)在较早阶段计算,并在调整窗口大小时再次触发。但是,我不知道何时以及我需要做什么来触发它。
有谁有想法,怎么解决这个问题?
编辑:当我在PopupView中有一个Tree组件或一个DateField组件,然后展开一个树元素或通过从Date弹出窗口中选择一个值来更改DateField的值时,调整大小正确完成,一切都很好。
我认为在您的情况下,检查浏览器窗口大小和计算目标像素大小的方法对于您的情况来说太复杂了。我建议只需将弹出窗口的宽度设置为100%,将高度设置为33%,如component.setHeight("33%")
,是的,您可以使用百分比来表示宽度和高度而不是像素。然后通过CSS完成大小调整,它将对浏览器窗口大小做出更快的反应而无需服务器往返。