首页 > 解决方案 > 如何使用 setItems for grid 将数据添加到 Vaadin 中的 CRUD?

问题描述

我将向 Vaadin 中的 CRUD 组件添加数据。这是一个简单的问题。但是我遇到的问题是,我无法通过首先获取grid对象然后将其项目设置给它来将数据添加到 CRUD。

这是我的 Vaadin 课程。这个类首先开始从 JPA Spring 数据库中获取数据。好的。那是有效的。并且数据被传输到一个名为的集合crudData中。然后crudData是众生设置crud.getGrid().setItems(crudData);,这是行不通的。我假设如果我从 CRUD 获得网格,那么我也可以设置网格项,然后它们将显示在 CRUD 上......但没有......

@Data
public class StocksCrud {

    private Crud<StockNames> crud;

    private List<StockNames> crudData;

    private StockNamesRepository stockNamesRepository;


    private CrudEditor<StockNames> createStocksEditor() {
        TextField stockName = new TextField("Name of the stock");
        FormLayout form = new FormLayout(stockName);

        Binder<StockNames> binder = new Binder<>(StockNames.class);
        binder.bind(stockName, StockNames::getStockName, StockNames::setStockName);

        return new BinderCrudEditor<>(binder, form);
    }

    public StocksCrud(StockNamesRepository stockNamesRepository) {
        this.stockNamesRepository = stockNamesRepository;

        // Fill the crud
        crudData = new ArrayList<StockNames>();
        for(StockNames stockName: stockNamesRepository.findAll()) {
            crudData.add(new StockNames(stockName.getId(), stockName.getStockName()));
        }

        // Crate crud table
        crud = new Crud<>(StockNames.class, createStocksEditor());
        crud.getGrid().setItems(crudData); // This won't work
        crud.addSaveListener(e -> saveStock(e.getItem()));
        crud.addDeleteListener(e -> deleteStock(e.getItem()));
        crud.getGrid().removeColumnByKey("id");
        crud.addThemeVariants(CrudVariant.NO_BORDER);
    }

    private void deleteStock(StockNames stockNames) {
        boolean exist = stockNamesRepository.existsBystockName(stockNames.getStockName());
        if(exist == true) {
            crudData.remove(stockNames);
            stockNamesRepository.delete(stockNames);
        }
    }

    private void saveStock(StockNames stockNames) {
        System.out.println(stockNames == null);
        System.out.println(stockNamesRepository == null);
        boolean exist = stockNamesRepository.existsBystockName(stockNames.getStockName());
        if(exist == false) {
            crudData.add(stockNames);
            stockNamesRepository.save(stockNames);
        }
    }   

}

这是我的错误输出:

java.lang.ClassCastException: com.vaadin.flow.component.crud.CrudFilter cannot be cast to com.vaadin.flow.function.SerializablePredicate

我知道有一种方法可以通过使用数据提供程序类在 Vaadin 中将数据设置为 CRUD。但我不想用那个。这是....太多的代码。我想保持干净并用 Java 编写更少的代码。底部的示例:https ://vaadin.com/components/vaadin-crud/java-examples

@Entity
@Data
@NoArgsConstructor
public class StockNames implements Cloneable{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private String stockName;

    public StockNames(int id, String stockName) {
        this.id = id;
        this.stockName = stockName;
    }
}

更新:

这是我现在的代码

@Data
public class StocksCrud {

    private Crud<StockNames> crud;

    private List<StockNames> crudData;

    private StockNamesRepository stockNamesRepository;


    private CrudEditor<StockNames> createStocksEditor() {
        TextField stockName = new TextField("Name of the stock");
        FormLayout form = new FormLayout(stockName);

        Binder<StockNames> binder = new Binder<>(StockNames.class);
        binder.bind(stockName, StockNames::getStockName, StockNames::setStockName);

        return new BinderCrudEditor<>(binder, form);
    }

    public StocksCrud(StockNamesRepository stockNamesRepository) {
        this.stockNamesRepository = stockNamesRepository;

        // Fill the crud
        crudData = new ArrayList<StockNames>();
        for(StockNames stockName: stockNamesRepository.findAll()) {
            crudData.add(new StockNames(stockName.getId(), stockName.getStockName()));
        }

        // Create grid
        Grid<StockNames> grid = new Grid<StockNames>();
        grid.setItems(crudData);

        // Crate crud table
        crud = new Crud<>(StockNames.class, createStocksEditor());
        crud.setGrid(grid);
        crud.addSaveListener(e -> saveStock(e.getItem()));
        crud.addDeleteListener(e -> deleteStock(e.getItem()));
        //crud.getGrid().removeColumnByKey("id");
        crud.addThemeVariants(CrudVariant.NO_BORDER);
    }

    private void deleteStock(StockNames stockNames) {
        boolean exist = stockNamesRepository.existsBystockName(stockNames.getStockName());
        if(exist == true) {
            crudData.remove(stockNames);
            stockNamesRepository.delete(stockNames);
        }
    }

    private void saveStock(StockNames stockNames) {
        System.out.println(stockNames == null);
        System.out.println(stockNamesRepository == null);
        boolean exist = stockNamesRepository.existsBystockName(stockNames.getStockName());
        if(exist == false) {
            crudData.add(stockNames);
            stockNamesRepository.save(stockNames);
        }
    }   

}

更新 2:

这给出了一个错误。

// Create grid
        Grid<StockNames> grid = new Grid<StockNames>();
        StockNames s1 = new StockNames(1, "HELLO");
        crudData.add(s1);
        grid.setItems(crudData);

        // Crate crud table
        crud = new Crud<>(StockNames.class, createStocksEditor());
        crud.setGrid(grid);
        crud.addSaveListener(e -> saveStock(e.getItem()));
        crud.addDeleteListener(e -> deleteStock(e.getItem()));
        crud.getGrid().removeColumnByKey(grid.getColumns().get(0).getKey());
        crud.addThemeVariants(CrudVariant.NO_BORDER);

错误是:

 java.lang.IndexOutOfBoundsException: Index: 0, Size: 0'

什么?我刚刚添加了一个对象。

标签: springjpavaadincrud

解决方案


分配网格解决了这个问题

 Grid<StockNames> grid=new Grid<>(StockNames.class);
 crud = new Crud<>(StockNames.class,grid, createStocksEditor());

在您的代码示例中,您依赖于提供的默认实现Crud,因此CrudGrid正在创建。它的setDataProvider返回DataProvider<E,CrudFilter>,而 Grid 的 DataProvider 是类型:(AbstractDataProvider<T, SerializablePredicate<T>>这是因为您使用的是ListDataProvider,它扩展了AbstractDataProvider<T, SerializablePredicate<T>>)。这是错误状态:

java.lang.ClassCastException:com.vaadin.flow.component.crud。CrudFilter不能转换为 com.vaadin.flow.function。可序列化谓词

因此,如果您想通过网格分配值 - 您首先需要创建一个。否则,如文档中所示,您可以提供自定义数据提供者:PersonDataProvider

更新


这是我正在使用的示例代码。在我向 bean 添加一个无参数构造函数之后,在 Crud 中添加一个新项目是可行的:

import java.util.Random;

public class StockNames implements Cloneable{
    Random rnd=new Random();
    private int id;
    private String stockName;

    public StockNames(){
        //You will an id generated automatically for you, but here is just an example
        id=rnd.nextInt(12000);

    }

    public StockNames(int id, String stockName) {
        this.id = id;
        this.stockName = stockName;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getStockName() {
        return stockName;
    }

    public void setStockName(String stockName) {
        this.stockName = stockName;
    }
}

StockCrud班级:

import com.vaadin.flow.component.crud.*;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.router.Route;

import java.util.ArrayList;
import java.util.List;

@Route("crudLayout")
public class StockCrud extends VerticalLayout {

    private Crud<StockNames> crud;

    private List<StockNames> crudData;


    private CrudEditor<StockNames> createStocksEditor() {
        TextField stockName = new TextField("Name of the stock");
        FormLayout form = new FormLayout(stockName);

        Binder<StockNames> binder = new Binder<>(StockNames.class);
        binder.bind(stockName, StockNames::getStockName, StockNames::setStockName);

        return new BinderCrudEditor<>(binder, form);
    }

    public StockCrud() {

        // Fill the crud
        crudData = new ArrayList<StockNames>();
        for(int i=0;i<150;i++) {
            crudData.add(new StockNames(i,"Name " + i));
        }

        // Crate crud table
        Grid<StockNames> grid=new Grid<>(StockNames.class);
        crud = new Crud<>(StockNames.class,grid, createStocksEditor());
        //((CrudGrid )crud.getGrid()).setItems(crudData);
        crud.getGrid().setItems(crudData); // This won't work
        crud.addSaveListener(e -> saveStock(e.getItem()));
        crud.addDeleteListener(e -> deleteStock(e.getItem()));
       // crud.getGrid().removeColumnByKey("id");
        crud.addThemeVariants(CrudVariant.NO_BORDER);
        add(crud);
    }

    private void deleteStock(StockNames stockNames) {
       // if(crudData.contains(stockNames)) {
            crudData.remove(stockNames);
        //}
    }

    private void saveStock(StockNames stockNames) {
        System.out.println(stockNames == null);
        if(!crudData.contains(stockNames)) {
            crudData.add(stockNames);
        }
    }

}

推荐阅读