在 ComboBox 上添加新元素
Adding new elements on ComboBox
我正在开发一个 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 Model
和 ObjectItem
class,我必须使用它,因为我无法使用 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);
}
}
在调试这段代码后,我发现使用了 newElementHandler
,它向容器中添加了一个新项目,但是在 ComboBox
和下一个处理程序的执行中没有显示任何内容,容器是空的,好像没有插入任何项目。
我已经能够识别错误。当您 select ComboBox
中的一项时,filterString
变为 ""
,因此,如果您 select 数据库中不存在的内容,请回想一下查询,它不会在 List<Model> result
中,因此,它将未被 select 编辑。
克服这个问题的一种方法是修改 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();
});
这允许通过过滤器维护新项目。
我正在开发一个 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 Model
和 ObjectItem
class,我必须使用它,因为我无法使用 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);
}
}
在调试这段代码后,我发现使用了 newElementHandler
,它向容器中添加了一个新项目,但是在 ComboBox
和下一个处理程序的执行中没有显示任何内容,容器是空的,好像没有插入任何项目。
我已经能够识别错误。当您 select ComboBox
中的一项时,filterString
变为 ""
,因此,如果您 select 数据库中不存在的内容,请回想一下查询,它不会在 List<Model> result
中,因此,它将未被 select 编辑。
克服这个问题的一种方法是修改 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();
});
这允许通过过滤器维护新项目。