在ComboBox上添加新元素

时间:2017-11-13 16:25:50

标签: java combobox vaadin vaadin7

我正在开发一个Vaadin应用,我决定使用SuggestingComboBox这个想法,可以更好地搜索项目。这很好用,但现在我无法弄清楚如何使用setNewItemHandler方法添加尚未包含在容器中的新元素。
对于参考,这里是SuggestingComBox代码:

public class SuggestingComboBox extends ComboBox {

    public SuggestingComboBox() {
        setItemCaptionMode(ItemCaptionMode.PROPERTY);
        setItemCaptionPropertyId("name");
    }

    @Override
    protected Filter buildFilter(String filterString, 
            FilteringMode filteringMode) {
        return new SuggestingContainer.SuggestionFilter(filterString);
    }
}

组合框中出现的SuggestingContainer代码:

public abstract class SuggestingContainer<T> extends BeanItemContainer<T> {

    public SuggestingContainer(Class<? super T> type)
            throws IllegalArgumentException {
        super(type);
    }

    @Override
    protected void addFilter(Filter filter) 
            throws UnsupportedFilterException {
        if(filter instanceof SuggestionFilter) {
            SuggestionFilter suggestionFilter = (SuggestionFilter) filter;
            filterItems(suggestionFilter.getFilterString());
        } else 
            super.addFilter(filter);
    }

    //This method is to be overriden
    protected abstract void filterItems(String filterString);

   public static class SuggestionFilter implements Container.Filter {
       private String filterString;

       public SuggestionFilter(String filterString) {
           this.filterString = filterString;
       }

       public String getFilterString() {
           return filterString;
       }

       @Override
       public boolean passesFilter(Object itemId, Item item) 
               throws UnsupportedOperationException {
           return false;
       }

       @Override
       public boolean appliesToProperty(Object propertyId) {
           return false;
       }
  }

此容器用作:

public SuggestingField extends CustomField<Model> {
    private SuggestingComboBox suggestingCB;
    private SuggestingContainer<ObjectItem> container;

    public SuggestingField() {
        suggestingCB = new SuggestingComboBox();
        container = new SuggestingContainer<ObjectItem>(ObjectItem.class) {
            @Override
            protected void filterItems(String filterString) {               
                removeAllItems();

                List<Model> result; //Obtain here the results
                List<ObjectItem> lItems = result.stream()
                        .map(m -> new ObjectItem(m.getId()+"", m.toString(), m))
                        .collect(Collectors.toList());
                addAll(lItems);
            }
        };
        suggestingCB.setContainerDataSource(container);
        suggestingCB.setImmediate(true);
        suggestingCB.setItemCaptionPropertyId("text");
    }
}

另外,我有一个POJO ModelObjectItem类,我必须使用,因为我无法使用toString字幕模式。

public class Model {
    private int id;
    private String name;
    //Getters and setters; equals/hash
}
public class ObjectItem {
    private String id;
    private String text;
    private Object o;
    //Equals/hash and getters/setters
}

所以,我的问题是:我正在尝试允许使用Model方法在字段中创建新的setNewItemHandler(s)。这是我到目前为止所尝试过的。

public SuggestingField extends CustomField<Model> {
...
    public void setNewElementsAllowed(boolean allowed) {
        this.suggestingCB.setNewItemsAllowed(allowed);
        this.suggestingCB.setImmediate(allowed);
        if(allowed) {
            suggestingCB.setNewItemHandler(caption -> {
                Model m = new Model();
                m.setNombre(caption);

                setValue(m);
            });
        }
    }
    public void setValue(Model m) {
        super.setValue(m);
        if(m == null)
            suggestingCB.setValue(null);
        else {
            ObjectItem it = new ObjectItem(""+m.getId(),
                m.getName(), m);
            if(container.size() == 0 || !container.containsId(it.getId()))
                container.addItem(it);

            suggestingCB.setValue(it);
            suggestingCB.select(it);
        }
    }

调试完这段代码之后,我发现使用了newElementHandler,并且它向容器中添加了一个新项,但ComboBox和下一个处理程序的执行中没有显示任何内容,容器为空,好像没有插入任何项目。

1 个答案:

答案 0 :(得分:0)

我已经能够识别错误。当您在ComboBox中选择一个项目时,filterString会变为"",因此,如果您选择了数据库中没有的内容,并回想起查询,则会赢得&# 39; t在List<Model> result中,因此,它将被取消选择 解决此问题的一种方法是修改SuggestingField,如下所示:

public SuggestingField extends CustomField<Model> {
    private Model model;
    ...
    public SuggestingField() {
        ...
        container = new SuggestingContainer<ObjectItem>(ObjectItem.class) {
            @Override
            protected void filterItems(String filterString) {               
                removeAllItems();

                if("".equals(filterString)) {
                    if(model != null) {
                        ObjectItem it = new ObjectItem();
                        it.setId(model.getId()+"");
                        it.setText(model.toString());
                        it.setObject(model);

                        addItem(it);
                        return;
                    }
                }

                List<Model> result; //Obtain here the results
                List<ObjectItem> lItems = result.stream()
                    .map(m -> new ObjectItem(m.getId()+"", m.toString(), m))
                    .collect(Collectors.toList());
                addAll(lItems);
            }
        };
        suggestingCB.addValueChangeListener(ev -> {
            this.model = (Model) suggestingCB.getValue();
        });

这允许通过过滤器维护新项目。