如何在选择模式下使用多个ID "Property"
How to use multiple IDs in selection mode "Property"
我有一个选择组件(具体来说是一个组合框)并添加了一个 SQLContainer 作为 ContainerDataSource。
我已经通过 .setItemCaptionPropertyId("myID")
设置了 ItemCaption。但是,我需要使用两个属性作为标题。
假设 ID 为 "myID" 的属性表示类似 "foo" 的字符串。还有另一个名为 "myCodeID" 的 属性,它代表一个数字,如“23”。
如何让我的 ComboBox 将其项目的标题显示为“23 foo”?
我正在搜索类似 .setItemCaptionPropertyIds("myId", "myCodeID")
的内容。
我相信您可以使用多种方法,但至少以下两种方法有效:
1) 快速且 肮脏
如何使用 "fake property",这意味着您使用 object 上实际不存在的 属性,有一个 getter 具有该名称。由于 Vaadin will also look for getters/setters 在确定项目属性时,它会找到它并将其用于您的标题。
我知道必须修改您的模型并不是最优雅的做法 class,但它能让您做到这一点。此外,根据您的实施方式,您可以使用包含 getCaption()
方法的 PersonCaptionGenerator
来装饰 Person
,以保持分离。
假设你有这样一个 bean:
public static class Person {
private String name, surname;
private int age;
public Person(String name, String surname, int age) {
this.name = name;
this.surname = surname;
this.age = age;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
public void setName(String name) {
this.name = name;
}
public void setSurname(String surname) {
this.surname = surname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getCaption() {
// getter to be used as caption
return name + " " + surname;
}
}
然后你可以这样写:
public class ComboBoxComponent extends VerticalLayout {
public ComboBoxComponent() {
BeanItemContainer<Person> dataSource = new BeanItemContainer<>(HasCaption.class);
ComboBox comboBox = new ComboBox();
comboBox.setItemCaptionMode(AbstractSelect.ItemCaptionMode.PROPERTY);
// use a fake property which will get identified by the getter
comboBox.setItemCaptionPropertyId("caption");
addComponent(comboBox);
comboBox.setContainerDataSource(dataSource);
Random random = new Random();
for (int i = 0; i < 10; i++) {
dataSource.addBean(new Person("Name " + i, "Surname " + i, random.nextInt(99) + 1));
}
}
}
2) 扩展组合并添加一个 字幕生成器
如果您不能修改模型并且有一个有点通用和可重用的解决方案,您可以扩展 ComboBox
并覆盖 getItemCaption()
方法。请注意,我使用了 BeanItemContainer
因为它更容易,因为它将 bean 本身作为项目 ID,但如果需要不同的容器,它可能会被调整。
从相同的 Person
bean 开始,但没有 fake 属性.
的 getter
通用合同:
public interface CaptionComposer<T> {
String getCaption(T item);
}
我们的 Person
bean 的实现:
private class PersonCaptionGenerator implements CaptionComposer<Person> {
@Override
public String getCaption(Person person) {
return person.getName() + " " + person.getSurname();
}
}
将标题检索推迟到生成器的自定义组合框:
public static class MyComboBox<T> extends ComboBox {
private CaptionComposer captionComposer;
public MyComboBox(CaptionComposer<T> captionGenerator, BeanItemContainer<T> dataSource) {
this.captionComposer = captionGenerator;
setContainerDataSource(dataSource);
}
@Override
public String getItemCaption(Object itemId) {
return captionComposer.getCaption(itemId);
}
}
最后,将其添加到 UI:
public class ComboBoxComponent extends VerticalLayout {
public ComboBoxComponent() {
BeanItemContainer<Person> dataSource = new BeanItemContainer<>(Person.class);
addComponent(new MyComboBox<>(new PersonCaptionGenerator(), dataSource));
Random random = new Random();
for (int i = 0; i < 10; i++) {
dataSource.addBean(new Person("Name " + i, "Surname " + i, random.nextInt(99) + 1));
}
}
}
最后两者都会得到你:
我有一个选择组件(具体来说是一个组合框)并添加了一个 SQLContainer 作为 ContainerDataSource。
我已经通过 .setItemCaptionPropertyId("myID")
设置了 ItemCaption。但是,我需要使用两个属性作为标题。
假设 ID 为 "myID" 的属性表示类似 "foo" 的字符串。还有另一个名为 "myCodeID" 的 属性,它代表一个数字,如“23”。
如何让我的 ComboBox 将其项目的标题显示为“23 foo”?
我正在搜索类似 .setItemCaptionPropertyIds("myId", "myCodeID")
的内容。
我相信您可以使用多种方法,但至少以下两种方法有效:
1) 快速且 肮脏
如何使用 "fake property",这意味着您使用 object 上实际不存在的 属性,有一个 getter 具有该名称。由于 Vaadin will also look for getters/setters 在确定项目属性时,它会找到它并将其用于您的标题。
我知道必须修改您的模型并不是最优雅的做法 class,但它能让您做到这一点。此外,根据您的实施方式,您可以使用包含 getCaption()
方法的 PersonCaptionGenerator
来装饰 Person
,以保持分离。
假设你有这样一个 bean:
public static class Person {
private String name, surname;
private int age;
public Person(String name, String surname, int age) {
this.name = name;
this.surname = surname;
this.age = age;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
public void setName(String name) {
this.name = name;
}
public void setSurname(String surname) {
this.surname = surname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getCaption() {
// getter to be used as caption
return name + " " + surname;
}
}
然后你可以这样写:
public class ComboBoxComponent extends VerticalLayout {
public ComboBoxComponent() {
BeanItemContainer<Person> dataSource = new BeanItemContainer<>(HasCaption.class);
ComboBox comboBox = new ComboBox();
comboBox.setItemCaptionMode(AbstractSelect.ItemCaptionMode.PROPERTY);
// use a fake property which will get identified by the getter
comboBox.setItemCaptionPropertyId("caption");
addComponent(comboBox);
comboBox.setContainerDataSource(dataSource);
Random random = new Random();
for (int i = 0; i < 10; i++) {
dataSource.addBean(new Person("Name " + i, "Surname " + i, random.nextInt(99) + 1));
}
}
}
2) 扩展组合并添加一个 字幕生成器
如果您不能修改模型并且有一个有点通用和可重用的解决方案,您可以扩展 ComboBox
并覆盖 getItemCaption()
方法。请注意,我使用了 BeanItemContainer
因为它更容易,因为它将 bean 本身作为项目 ID,但如果需要不同的容器,它可能会被调整。
从相同的 Person
bean 开始,但没有 fake 属性.
通用合同:
public interface CaptionComposer<T> {
String getCaption(T item);
}
我们的 Person
bean 的实现:
private class PersonCaptionGenerator implements CaptionComposer<Person> {
@Override
public String getCaption(Person person) {
return person.getName() + " " + person.getSurname();
}
}
将标题检索推迟到生成器的自定义组合框:
public static class MyComboBox<T> extends ComboBox {
private CaptionComposer captionComposer;
public MyComboBox(CaptionComposer<T> captionGenerator, BeanItemContainer<T> dataSource) {
this.captionComposer = captionGenerator;
setContainerDataSource(dataSource);
}
@Override
public String getItemCaption(Object itemId) {
return captionComposer.getCaption(itemId);
}
}
最后,将其添加到 UI:
public class ComboBoxComponent extends VerticalLayout {
public ComboBoxComponent() {
BeanItemContainer<Person> dataSource = new BeanItemContainer<>(Person.class);
addComponent(new MyComboBox<>(new PersonCaptionGenerator(), dataSource));
Random random = new Random();
for (int i = 0; i < 10; i++) {
dataSource.addBean(new Person("Name " + i, "Surname " + i, random.nextInt(99) + 1));
}
}
}
最后两者都会得到你: