Как я могу добавить данные в CRUD в Vaadin, используя setItems для сетки? - PullRequest
0 голосов
/ 12 января 2020

Я собираюсь добавить данные в компонент CRUD в Vaadin. Это простой вопрос здесь. Но проблема, с которой я столкнулся, заключается в том, что я не могу добавить данные в CRUD, сначала получив объект grid, а затем установив его элементы.

Вот мой класс 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

Я знаю, что есть способ установить данные в CRUD в Vaadin, используя класс поставщика данных. Но я не хочу этим пользоваться. Это .... много кода. Я хочу сохранить его в чистоте и писать меньше кода в 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'

Что? Я только что добавил объект.

1 Ответ

3 голосов
/ 13 января 2020

Назначение сетки решает проблему

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

В вашем примере кода вы полагаетесь на реализацию по умолчанию, предоставленную Crud, таким образом, CrudGrid создается . Его setDataProvider возвращает DataProvider<E,CrudFilter>, тогда как DataProvider Grid имеет тип: AbstractDataProvider<T, SerializablePredicate<T>> (это потому, что вы используете ListDataProvider, который расширяет AbstractDataProvider<T, SerializablePredicate<T>>). Вот что сообщает об ошибке:

java .lang.ClassCastException: com.vaadin.flow.component.crud. CrudFilter нельзя преобразовать в com.vaadin.flow. function. SerializablePredicate

Так что, если вы хотите назначить значения через сетку, вам сначала нужно создать их. В противном случае, как показано в документации, вы можете предоставить пользовательский провайдер данных: PersonDataProvider

Обновление


Это пример кода, которым я являюсь с помощью. Добавление нового элемента в работы Crud после того, как я добавил конструктор без аргументов в bean-компонент:

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);
        }
    }

}
...