【问题标题】:Adding new elements on ComboBox在 ComboBox 上添加新元素
【发布时间】:2017-11-13 16:25:49
【问题描述】:

我正在开发一个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
}

所以,我的问题是:我正在尝试使用setNewItemHandler 方法在现场创建新的Model(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);
        }
    }

debuggind这段代码后,发现使用了newElementHandler,向容器中添加了一个新的item,但是ComboBox没有任何显示,下一个handler的执行,容器是空的,好像没有插入任何项目。

【问题讨论】:

  • 对不起,我似乎误读了您的问题并提供了错误的答案。会更新它。在public SuggestingField() { 的代码中是 suggestingCB = new SuggestingContainer(); 猜你想修复它。
  • 你如何初始化这个List&lt;Model&gt; result; //Obtain here the results
  • 我从数据库中获取它们。此列表是通过过滤符合filterString 的模型来填充的。另外,修正了那个误写。 @pirho。我已经找到解决方案,我会尽快添加它
  • 记录下来。我不确定过滤发生时情况如何。过滤时从容器中删除项目?当你在 cb 中写 anythinh 时会发生这种情况?
  • 是的,正如你所描述的。当ComboBox 检测到某些输入时,它会向服务器发送一个事件,该事件调用filterItems 方法。在这种方法中,我删除了所有内容,并得到了符合 filterString 的任何内容。

标签: java combobox vaadin vaadin7


【解决方案1】:

我已经能够识别错误。当您在 ComboBox 中选择一项时,filterString 将变为 "",因此,如果您选择了数据库中不存在的内容并调用查询,则它不会在 List&lt;Model&gt; 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();
        });

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

【讨论】:

    猜你喜欢
    • 2016-02-05
    • 2021-03-29
    • 2019-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-29
    • 2021-01-31
    • 2017-11-30
    相关资源
    最近更新 更多