Java Vaadin 14-在嵌套布局中使用时网格未显示/填充

Java Vaadin 14-在嵌套布局中使用时网格未显示/填充,java,spring-boot,vaadin,Java,Spring Boot,Vaadin,我正在尝试构建一个Vaadin/Spring应用程序。我使用的是Spring Security,应用程序的安全部分基于本文中的示例和信息。我的主/主视图非常简单,带有瓦丁网格: @SpringComponent @UIScope @Route(value = "", layout = MainLayout.class) public class MainView extends HorizontalLayout { private ItemService itemS

我正在尝试构建一个Vaadin/Spring应用程序。我使用的是Spring Security,应用程序的安全部分基于本文中的示例和信息。我的主/主视图非常简单,带有瓦丁网格:

@SpringComponent
@UIScope
@Route(value = "", layout = MainLayout.class)
public class MainView extends HorizontalLayout {

    private ItemService itemService;

    private Grid<ItemDTO> itemGrid;

    @Autowired
    public MainView(ItemService itemService) {
        this.itemService = itemService;
        var items = this.itemService.getItems();
        this.itemGrid = new Grid<>(ItemDTO.class);
        this.itemGrid.addColumn(ItemDTO::getName).setHeader("Name");
        this.itemGrid.addColumn(ItemDTO::getUnitId).setHeader("Unit");
        this.itemGrid.setItems(items);
        add(itemGrid);
    }

}
但是,在登录并重定向到
MainView
后,网格不会加载:

但是,如果我从MainView中删除
layout=MainLayout.class
,它将加载罚款。项目中的另一个视图同样使用Vaadin栅格并引用MainView,可以很好地加载:

@SpringComponent
@UIScope
@Route(value = "vendor", layout = MainLayout.class)
public class VendorView extends VerticalLayout implements HasUrlParameter<String> {

    private String prop;
    private Grid<VendorItemDTO> itemGrid;
    private VendorItemService vendorService;

    public VendorView(VendorItemService vendorService) {
        this.vendorService = vendorService;

    }

    @Override
    public void setParameter(BeforeEvent event, String parameter) {
        this.prop = parameter;
        this.setUpUI();
    }

    private void setUpUI() {
        var items = this.vendorService.findByVendor(prop);
        var h2 = new H2("Items for " + this.prop);

        this.itemGrid = new Grid<>();
        this.itemGrid.addColumn(VendorItemDTO::getItemName).setHeader("Item");
        this.itemGrid.addColumn(VendorItemDTO::getTotalPrice).setHeader("Total Price");
        this.itemGrid.addColumn(VendorItemDTO::getUnitString).setHeader("Units");
        this.itemGrid.setItems(items);

        add(h2, itemGrid);
    }

}
@SpringComponent
@望远镜
@路线(value=“vendor”,layout=MainLayout.class)
公共类VendorView扩展了VerticalLayout,实现了HasUrlParameter{
私人弦道具;
私有网格;
私人供应商服务供应商服务;
公共供应商视图(供应商服务供应商服务){
this.vendorService=vendorService;
}
@凌驾
公共void setParameter(BeforeEvent事件,字符串参数){
this.prop=参数;
这是setUpUI();
}
私有void setUpUI(){
var items=this.vendorService.findByVendor(prop);
var h2=新h2(“项目+此.prop”);
this.itemGrid=新网格();
this.itemGrid.addColumn(VendorItemDTO::getItemName).setHeader(“项”);
this.itemGrid.addColumn(VendorItemDTO::getTotalPrice).setHeader(“总价”);
this.itemGrid.addColumn(VendorItemDTO::getUnitString).setHeader(“单位”);
this.itemGrid.setItems(items);
添加(h2,itemGrid);
}
}
这是我第一次使用Vaadin,因此,如果这是一个明显的错误,我深表歉意,但我参考了该项目的文档和视频,尚未解决该问题


谢谢。

我遇到了几乎相同的问题,只是设置有点不同,这里是链接到正确代码示例的答案,感谢@Erik Lumme-

在我的例子中,自从我开始使用嵌套布局引擎后,网格就消失了。浏览器工具的使用表明网格以html形式存在,但有样式参数“position:relative”,并且被布局的底部元素溢出

解决方案几乎是一样的——我在包含网格的“container”元素中添加了.setFullSize()。在那之后,我制作了maven:clean,然后重建了项目以使其正常工作

下面是代码引用(通过提供的链接可以找到完整的示例):

主要布局:

@Theme(value = Material.class, variant = Material.DARK)
public class MainLayout extends Composite<VerticalLayout> implements RouterLayout {

    //Component to delegate content through.
    private Div mainContent = new Div();           //**!!!the "conteiner" element**

    public MainLayout() {
        getContent().add(
                new Span("from MainLayout top"),
                mainContent,
                new Span("from MainLayout bottom"));
        mainContent.setSizeFull();                  //**!!!.setFullSize applied**
    }

    @Override
    public void showRouterLayoutContent(HasElement hasElement) {
        Objects.requireNonNull(hasElement);
        Objects.requireNonNull(hasElement.getElement());
        mainContent.removeAll();
        mainContent.getElement().appendChild(hasElement.getElement());
    }
}
@Theme(value=Material.class,variant=Material.DARK)
公共类MainLayout扩展复合实现RouterLayout{
//组件来委派内容。
private Div mainContent=new Div();//**!“contenner”元素**
公共主布局图(){
getContent().add(
新跨度(“从主布局顶部开始”),
主要内容,,
新跨度(“从主布局底部”);
mainContent.setSizeFull();//**!。已应用setFullSize**
}
@凌驾
公共无效showRouterLayoutContent(HasElement HasElement){
对象。requirennull(hasElement);
Objects.requireNonNull(hasElement.getElement());
mainContent.removeAll();
mainContent.getElement().appendChild(hasElement.getElement());
}
}
菜单栏布局:

@ParentLayout(value = MainLayout.class)
public class LayoutWithMenuBar extends Composite<VerticalLayout> implements RouterLayout {

    private Div mainContent = new Div();   //**!!! the container element**

    private HorizontalLayout menuBar = new HorizontalLayout(
            new RouterLink("Tprojects", TProjectDashboard.class));

    public LayoutWithMenuBar() {
        getContent().add(menuBar, mainContent);
        mainContent.setSizeFull();              //**!!! .setFullSize() applied**
    }

    @Override
    public void showRouterLayoutContent(HasElement hasElement) {
        Objects.requireNonNull(hasElement);
        Objects.requireNonNull(hasElement.getElement());
        mainContent.removeAll();
        mainContent.getElement().appendChild(hasElement.getElement());
    }
}
@ParentLayout(value=MainLayout.class)
带有菜单栏的公共类LayoutWithMenuBar扩展复合实现RouterLayout{
private Div mainContent=new Div();//**!容器元素**
private HorizontalLayout菜单栏=新建HorizontalLayout(
新的RouterLink(“Tprojects”,TProjectDashboard.class));
带菜单栏的公共布局(){
getContent().add(菜单栏,mainContent);
mainContent.setSizeFull();//**!。已应用setFullSize()**
}
@凌驾
公共无效showRouterLayoutContent(HasElement HasElement){
对象。requirennull(hasElement);
Objects.requireNonNull(hasElement.getElement());
mainContent.removeAll();
mainContent.getElement().appendChild(hasElement.getElement());
}
}
最后,网格本身:

@Route(value = "dashboard/tproject", layout = LayoutWithMenuBar.class)
public class TProjectDashboard extends VerticalLayout {

    private Grid<TProject> tprojectGrid = new Grid<>(TProject.class);

    public TProjectDashboard() {

        tprojectGrid.setItems(
                new TProject("Erik", "Software Engineer"),
                new TProject("Fia", "Kindergarden teacher"),
                new TProject("Jack", "All trades")
        );

        add(tprojectGrid);
    }
}
@Route(value=“dashboard/tproject”,layout=LayoutWithMenuBar.class)
公共类TProjectDashboard扩展了垂直布局{
私有网格tprojectGrid=新网格(TProject.class);
公共TProjectDashboard(){
tprojectGrid.setItems(
新项目(“Erik”,“软件工程师”),
新项目(“Fia”,“幼儿园教师”),
新项目(“杰克”、“所有行业”)
);
添加(tprojectGrid);
}
}

该解决方案由@Erik Lumme在此处提供-

在浏览器开发工具中,检查
元素是否存在于
主视图中。由于某种原因,它的宽度/高度可能为0。由于vaadin 14,每次在项目中引入新组件时,您都必须使用“prepare frontend”进行重建。否则将不会显示组件。感谢您的回复。事实证明,@Tazavoo是正确的——网格(或者它的容器)没有明显的宽度。只需调用
setWidthFull()
即可轻松解决此问题。事后看来,我想这应该是显而易见的,但我仍然不完全理解为什么在其他两种情况下(当
layout=
被删除,而对于另一种视图)没有出现这种情况时,该网格的宽度为0。我想我还有很多关于这个框架的知识要学习。多亏了那些烦人的受访者。这不是很明显,我自己也遇到过好几次,这是瓦丁可以改进的。根本原因是一个视图是垂直布局
,另一个视图是水平布局。在垂直布局中,孩子们根据需要选择全宽和全高。在水平方向上,它们根据需要选择全高和全宽。公寓
@Route(value = "dashboard/tproject", layout = LayoutWithMenuBar.class)
public class TProjectDashboard extends VerticalLayout {

    private Grid<TProject> tprojectGrid = new Grid<>(TProject.class);

    public TProjectDashboard() {

        tprojectGrid.setItems(
                new TProject("Erik", "Software Engineer"),
                new TProject("Fia", "Kindergarden teacher"),
                new TProject("Jack", "All trades")
        );

        add(tprojectGrid);
    }
}