update vaadin grid when new record added to database

故事扮演 提交于 2019-12-23 01:52:58

问题


I want to add the element to the table in the database and update the grid with new data (probably I should add records directly on UI to the table but whatever).

My grid component looks like this

@SpringComponent
public class PlayersGrid extends Grid<Player> {

    @PostConstruct
    public void afterInit() {
        addColumn(Player::getId).setHeader("ID");
        addColumn(Player::getName).setHeader("Name");
        addColumn(Player::getCharacterClass).setHeader("Class");
        addColumn(Player::getLevel).setHeader("Level");
    }

    public class GridContentObserver implements ContentObserver {

        @Override
        public void refreshContent() {
            PlayersGrid.this.getDataProvider().refreshAll();
        }
    }
}

I add players via form that looks like this

@SpringComponent
public class CharacterCreationForm extends FormLayout {
    private static final Logger LOGGER = LoggerFactory.getLogger(CharacterCreationForm.class);

    private List<ContentObserver> boundObservers = new ArrayList<>();

    private TextField name;
    private TextField characterClass;
    private TextField level;

    @Autowired
    private PlayerRepository repository;

    @PostConstruct
    public void create() {
        name = new TextField();
        characterClass = new TextField();
        level = new TextField();

        addFormItem(name, "Name");
        addFormItem(characterClass, "Class");
        addFormItem(level, "Level");

        Binder<Player> binder = new Binder<>(Player.class);

        binder
            .forField(level)
            .withConverter(new StringToIntegerConverter(0, ""))
            .bind(Player::getLevel, Player::setLevel);

        binder.bindInstanceFields(this);

        Button button = new Button("Save");
        button.addClickListener(buttonClickEvent -> {
            try {
                Player newPlayer = new Player();
                binder.writeBean(newPlayer);
                LOGGER.info("Attempt to write object: {}", newPlayer);

                repository.save(newPlayer);
                // notify observers
                boundObservers.forEach(ContentObserver::refreshContent);
            } catch (ValidationException e) {
                e.printStackTrace();
            }
        });

        add(button);
    }

    public void addObserver(ContentObserver observer) {
        boundObservers.add(observer);
    }

}

My main view in the application looks like this

public MainView(PlayerRepository repository, PlayersGrid grid, CharacterCreationForm form) {
    form.addObserver(grid.new GridContentObserver());
    form.setWidth("30%");

    // find the way to set items in the component
    grid.setItems(repository.findAll());

    HorizontalLayout horizontalLayout = new HorizontalLayout();
    horizontalLayout.add(form);

    VerticalLayout verticalLayout = new VerticalLayout();
    verticalLayout.add(grid, form);
    verticalLayout.setHeight("100%");
    add(verticalLayout);

    setClassName("main-layout");
}

On startup I have all my stored players in the grid. But when I save new ones using form it adds new records in the database, but doesn't update the grid.

What is wrong?


回答1:


Try the below changes that i think would make the code more clear and solve the issue with the ContentObserver

(didn't run the code so i'm not sure about compilation problems!)

change 1: PlayersGrid implements ContentObserver instead of having inner class

@SpringComponent
public class PlayersGrid extends Grid<Player> implements ContentObserver {

    @PostConstruct
    public void afterInit() {
        addColumn(Player::getId).setHeader("ID");
        addColumn(Player::getName).setHeader("Name");
        addColumn(Player::getCharacterClass).setHeader("Class");
        addColumn(Player::getLevel).setHeader("Level");
    }

    @Override
    public void refreshContent() {
        this.getDataProvider().refreshAll();
    }
}

change 2: boundObservers.forEach

@SpringComponent
public class CharacterCreationForm extends FormLayout {
    private static final Logger LOGGER = 
            LoggerFactory.getLogger(CharacterCreationForm.class);

    private List<ContentObserver> boundObservers = new ArrayList<>();

    private TextField name;
    private TextField characterClass;
    private TextField level;

    @Autowired
    private PlayerRepository repository;

    @PostConstruct
    public void create() {
        name = new TextField();
        characterClass = new TextField();
        level = new TextField();

        addFormItem(name, "Name");
        addFormItem(characterClass, "Class");
        addFormItem(level, "Level");

        Binder<Player> binder = new Binder<>(Player.class);

        binder
            .forField(level)
            .withConverter(new StringToIntegerConverter(0, ""))
            .bind(Player::getLevel, Player::setLevel);

        binder.bindInstanceFields(this);

        Button button = new Button("Save");
        button.addClickListener(buttonClickEvent -> {
            try {
                Player newPlayer = new Player();
                binder.writeBean(newPlayer);
                LOGGER.info("Attempt to write object: {}", newPlayer);

                repository.save(newPlayer);
                // notify observers

                // updated
                boundObservers.forEach( observer -> observer.refreshContent() );

            } catch (ValidationException e) {
                e.printStackTrace();
            }
        });

        add(button);
    }

    public void addObserver(ContentObserver observer) {
        boundObservers.add(observer);
    }

}

change 3: grid is now also the ContentObserver, so its easier to manage and understand.

public MainView(PlayerRepository repository, PlayersGrid grid, CharacterCreationForm form) {
    // updated
    form.addObserver(grid);
    form.setWidth("30%");

    // find the way to set items in the component
    grid.setItems(repository.findAll());

    HorizontalLayout horizontalLayout = new HorizontalLayout();
    horizontalLayout.add(form);

    VerticalLayout verticalLayout = new VerticalLayout();
    verticalLayout.add(grid, form);
    verticalLayout.setHeight("100%");
    add(verticalLayout);

    setClassName("main-layout");
}


来源:https://stackoverflow.com/questions/51686153/update-vaadin-grid-when-new-record-added-to-database

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!