Vaadin 8:取消选择时未触发绑定的 CheckBoxGroup SelectionListener

Vaadin 8: Binded CheckBoxGroup SelectionListener not fired on deselection

我正在努力检测绑定到 bean 的 CheckBoxGroup 中项目的 deselection。这是一个简化的例子:

我有一个class:

package com.vaadin.test;

import java.util.Date;
import java.util.Set;

public class Person {

    private String name;
    private Set<Tag> tags;

    public Person(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Tag> getTags() {
        return tags;
    }

    public void setTags(Set<Tag> tags) {
        this.tags = tags;
    }
}

class "Person" 的一个对象可以有很多 标签。 class 标签如下所示:

package com.vaadin.test;

public class Tag {

    private String name;

    public Tag(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj != null && obj.getClass().equals(Tag.class)) {
            return ((Tag) obj).getName().equals(this.getName());
        }
        return super.equals(obj);
    }
}

我用一个 TextField、一个 CheckBoxGroup 和一个 Binder 创建了一个简单的 UI:

import com.vaadin.ui.CheckBoxGroup;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

@Theme("valo")
public class TestUI
        extends UI {

    private static final long serialVersionUID = 1L;

    @Override
    protected void init(VaadinRequest request) {

        Person person = new Person("Marcus");
        person.setTags(new HashSet<Tag>() {{ add(new Tag("Foo")); add(new Tag("Bar")); }});

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

        TextField name = new TextField();
        binder.bind(name, Person::getName, Person::setName);

        CheckBoxGroup<Tag> tags = new CheckBoxGroup<>();
        tags.setItems(new HashSet<Tag>() {{ add(new Tag("Foo")); add(new Tag("Bar")); add(new Tag("Test")); }});
        tags.addSelectionListener(e -> {

            Set<Tag> selectedTags = e.getAllSelectedItems();
            Set<Tag> addedTags = e.getAddedSelection();
            Set<Tag> newTags = e.getNewSelection();
            Set<Tag> oldTags = e.getOldSelection();
            Set<Tag> removedTags = e.getRemovedSelection();
        });
        binder.bind(tags, Person::getTags, Person::setTags);

        this.setContent(new VerticalLayout(new Label("Hello Vaadin!"), name, tags));

        binder.setBean(person);
    }
}

结果如下所示:

当我 select and/or deselect CheckBox "Test" CheckBoxGroup 的 SelectionListener 被触发时,我可以处理更改的 selection .但是,如果我 deselect and/or (re)select CheckBoxes "Bar" 或 "Foo" 之一,则不会触发 SelectionListener。

如何处理取消选择绑定到 Bean 的 CheckBoxGroup 中预selected CheckBox 的问题?

提前致谢。

Tag class 中的 equals 方法看起来不对。您也可以从 hashCode 中受益。

进行这些编辑后,您的选择侦听器将正确触发:

public class Tag {

    private String name;

    public Tag(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Tag tag = (Tag) o;

        return name.equals(tag.name);
    }

    @Override
    public int hashCode() {
        return name.hashCode();
    }

}