数据绑定后 ComboBox 不可编辑
ComboBox not editable after data binding
Google-fu 没有显示任何内容,Whosebug 搜索显示了类似的问题机器人,但与我的情况不完全相同。男孩,我在这里问了很多问题。
这不是考试题、家庭作业题或学校项目等。所以请不要费心回复这样的评论。那对我学习没有帮助
简单地说,我有一个项目存储在数据库中:
barcode (bigint)
、check_out_date (datetime)
、due_date (datetime)
、is_available (String: True/False/Null
,我认为它比 UI 一侧的复选框更容易,比在数据库中使用 bit(1),因为我无法正确绑定。)is_late (String: True/False/Null, same reason as above)
、name (varchar)
、notes (varchar)
、type (varchar)
is_late
和 is_available
绑定到 2 个值的组合框 (True/False),数据库读取这些值并实际显示组合框中的值,但我无法编辑它们。作为参考,我在程序的不同部分还有 2 个其他组合框,但它们没有绑定,因此可以工作。
我怎样才能使(强制?)这些组合框可编辑?感谢您的帮助,我很高兴能加入这个社区!
相关代码:如果您看到 formatting/bracket 错误,那是因为我省略了所有实际有效的代码。该程序编译并 运行 w/o 问题。
private class editPanel extends FormLayout {
private InventoryItem item;
private TextField itemName, itemType, itemBarcode;
private DateField checkOutDate, dueDate;
private Button save, delete, cancel;
private ComboBox<String> isAvailable, isLate;
private TextArea notes;
private Binder<InventoryItem> binder = new Binder<>(InventoryItem.class);
public editPanel() {
initEditConf();
initEditLayout();
addListeners();
setSizeUndefined();
Responsive.makeResponsive(this);
binder.bindInstanceFields(this);
}
private void addListeners() {
isAvailable.addValueChangeListener(e -> {
System.out.println("Test"); //still not editable with a listener
//and still not editable by explicitly calling setEnabled(true), setReadOnly(false);
});
private void initEditLayout() {
isAvailable = new ComboBox<String>("Availability");
isAvailable.setItems("True", "False"); //should be managed by sys too
isLate = new ComboBox<String>("Overdue");
isLate.setEnabled(false);
isLate.setDescription("Value is managed by the system");
isLate.setIcon(VaadinIcons.QUESTION_CIRCLE_O);
//isAvailable = new TextField("Availability");
//isAvailable.setEnabled(false);
//isLate = new TextField("Overdue");
//isLate.setEnabled(false);
cancel.addClickListener(e -> this.cancel());
save.addClickListener(e -> this.save());
delete.addClickListener(e -> this.delete());
binder.forMemberField(checkOutDate).withConverter(new LocalDateToDateConverter());
binder.forMemberField(dueDate).withConverter(new LocalDateToDateConverter());
binder.forMemberField(itemName).asRequired().withValidator((string -> string != null && !string.isEmpty()), "Values cannot be empty").bind("name");
binder.forMemberField(itemType).asRequired().withValidator((string -> string != null && !string.isEmpty()), "Values cannot be empty").bind("type");
binder.forMemberField(itemBarcode).withConverter(new StringToLongConverter(itemBarcode.getValue())).bind("barcode");
binder.forMemberField(isAvailable).bind("isAvailable");
binder.forMemberField(isLate).bind("isLate");
}
项目class
@Table(name="item")
@Entity
public class InventoryItem implements Serializable, Cloneable {
private static final long serialVersionUID = 5592334329765505365L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long barcode;
@NotNull
private String name, type;
@Nullable
private String notes;
@Nullable
private String isAvailable, isLate;
@Nullable
@Temporal(TemporalType.TIMESTAMP)
private Date checkOutDate, dueDate;
public InventoryItem() {}
/* Excess constructors omitted */
@Column(name="barcode")
public Long getBarcode() {return barcode;}
public void setBarcode(Long barcode) {this.barcode = barcode;}
@Column(name="name")
public String getName() {return name;}
public void setName(String name) {this.name = name;}
@Column(name="type")
public String getType() {return type;}
public void setType(String type) {this.type = type;}
@Column(name="is_late")
public String getisLate() {return isLate;}
public void setLate(String isLate) {this.isLate = isLate;}
@Column(name="availability")
public String getisAvailable() {return isAvailable;}
public void setAvailable(String isAvailable) {this.isAvailable = isAvailable;}
@Column(name="notes") //bigtext?
public String getNotes() {return notes;}
public void setNotes(String notes) {this.notes = notes;}
@Column(name="check_out_date", columnDefinition="DATETIME")
public Date getCheckOutDate() {return checkOutDate;}
public void setCheckOutDate(Date checkOutDate) {this.checkOutDate = checkOutDate;}
@Column(name="due_date", columnDefinition="DATETIME")
public Date getDueDate() {return dueDate;}
public void setDueDate(Date dueDate) {this.dueDate = dueDate;}
}
我真丢人!原来我的 setter 命名不正确.. 因此能够读取但不能写入。
字段和实例数据是"isAvailable",所以系统正在寻找InventoryItem.setisAvailable(String available),但是方法被命名为
setAvailable.
当使用 binder.forField(field).bind(Object::getter, Object::setter)
时,该解决方案有效。只需传递您的方法名称。
但是、binder.forMemberField(field).bind("value")
分别在对象的class 中寻找getValue
和setValue
方法。在这种情况下,您的选择是修改您的 getter/setter 名称或使用 binder.forField
很好地解决了您的问题!
setAvailable
和 getIsAvailable
不是很好的方法名称,因为它们不匹配。因此,正如您所想,使用 setIsAvailable
或将 属性 更改为 available
并使用 setAvailable
/getAvailable
是正确的方法。
Vaadin Binder 使用 Java PropertyDescriptor 来查找 getters 和 setter。这只是在大写的 属性 名称之前添加 get
或 set
前缀的情况。
如果您使用布尔值,is
前缀也可以用于 getter,如 from the source code.
在那种情况下,您可以使用布尔值 属性 available
,然后使用 setAvailable
和 isAvailable
访问器方法。
Google-fu 没有显示任何内容,Whosebug 搜索显示了类似的问题机器人,但与我的情况不完全相同。男孩,我在这里问了很多问题。
这不是考试题、家庭作业题或学校项目等。所以请不要费心回复这样的评论。那对我学习没有帮助
简单地说,我有一个项目存储在数据库中:
barcode (bigint)
、check_out_date (datetime)
、due_date (datetime)
、is_available (String: True/False/Null
,我认为它比 UI 一侧的复选框更容易,比在数据库中使用 bit(1),因为我无法正确绑定。)is_late (String: True/False/Null, same reason as above)
、name (varchar)
、notes (varchar)
、type (varchar)
is_late
和 is_available
绑定到 2 个值的组合框 (True/False),数据库读取这些值并实际显示组合框中的值,但我无法编辑它们。作为参考,我在程序的不同部分还有 2 个其他组合框,但它们没有绑定,因此可以工作。
我怎样才能使(强制?)这些组合框可编辑?感谢您的帮助,我很高兴能加入这个社区!
相关代码:如果您看到 formatting/bracket 错误,那是因为我省略了所有实际有效的代码。该程序编译并 运行 w/o 问题。
private class editPanel extends FormLayout {
private InventoryItem item;
private TextField itemName, itemType, itemBarcode;
private DateField checkOutDate, dueDate;
private Button save, delete, cancel;
private ComboBox<String> isAvailable, isLate;
private TextArea notes;
private Binder<InventoryItem> binder = new Binder<>(InventoryItem.class);
public editPanel() {
initEditConf();
initEditLayout();
addListeners();
setSizeUndefined();
Responsive.makeResponsive(this);
binder.bindInstanceFields(this);
}
private void addListeners() {
isAvailable.addValueChangeListener(e -> {
System.out.println("Test"); //still not editable with a listener
//and still not editable by explicitly calling setEnabled(true), setReadOnly(false);
});
private void initEditLayout() {
isAvailable = new ComboBox<String>("Availability");
isAvailable.setItems("True", "False"); //should be managed by sys too
isLate = new ComboBox<String>("Overdue");
isLate.setEnabled(false);
isLate.setDescription("Value is managed by the system");
isLate.setIcon(VaadinIcons.QUESTION_CIRCLE_O);
//isAvailable = new TextField("Availability");
//isAvailable.setEnabled(false);
//isLate = new TextField("Overdue");
//isLate.setEnabled(false);
cancel.addClickListener(e -> this.cancel());
save.addClickListener(e -> this.save());
delete.addClickListener(e -> this.delete());
binder.forMemberField(checkOutDate).withConverter(new LocalDateToDateConverter());
binder.forMemberField(dueDate).withConverter(new LocalDateToDateConverter());
binder.forMemberField(itemName).asRequired().withValidator((string -> string != null && !string.isEmpty()), "Values cannot be empty").bind("name");
binder.forMemberField(itemType).asRequired().withValidator((string -> string != null && !string.isEmpty()), "Values cannot be empty").bind("type");
binder.forMemberField(itemBarcode).withConverter(new StringToLongConverter(itemBarcode.getValue())).bind("barcode");
binder.forMemberField(isAvailable).bind("isAvailable");
binder.forMemberField(isLate).bind("isLate");
}
项目class
@Table(name="item")
@Entity
public class InventoryItem implements Serializable, Cloneable {
private static final long serialVersionUID = 5592334329765505365L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long barcode;
@NotNull
private String name, type;
@Nullable
private String notes;
@Nullable
private String isAvailable, isLate;
@Nullable
@Temporal(TemporalType.TIMESTAMP)
private Date checkOutDate, dueDate;
public InventoryItem() {}
/* Excess constructors omitted */
@Column(name="barcode")
public Long getBarcode() {return barcode;}
public void setBarcode(Long barcode) {this.barcode = barcode;}
@Column(name="name")
public String getName() {return name;}
public void setName(String name) {this.name = name;}
@Column(name="type")
public String getType() {return type;}
public void setType(String type) {this.type = type;}
@Column(name="is_late")
public String getisLate() {return isLate;}
public void setLate(String isLate) {this.isLate = isLate;}
@Column(name="availability")
public String getisAvailable() {return isAvailable;}
public void setAvailable(String isAvailable) {this.isAvailable = isAvailable;}
@Column(name="notes") //bigtext?
public String getNotes() {return notes;}
public void setNotes(String notes) {this.notes = notes;}
@Column(name="check_out_date", columnDefinition="DATETIME")
public Date getCheckOutDate() {return checkOutDate;}
public void setCheckOutDate(Date checkOutDate) {this.checkOutDate = checkOutDate;}
@Column(name="due_date", columnDefinition="DATETIME")
public Date getDueDate() {return dueDate;}
public void setDueDate(Date dueDate) {this.dueDate = dueDate;}
}
我真丢人!原来我的 setter 命名不正确.. 因此能够读取但不能写入。
字段和实例数据是"isAvailable",所以系统正在寻找InventoryItem.setisAvailable(String available),但是方法被命名为 setAvailable.
当使用 binder.forField(field).bind(Object::getter, Object::setter)
时,该解决方案有效。只需传递您的方法名称。
但是、binder.forMemberField(field).bind("value")
分别在对象的class 中寻找getValue
和setValue
方法。在这种情况下,您的选择是修改您的 getter/setter 名称或使用 binder.forField
很好地解决了您的问题!
setAvailable
和 getIsAvailable
不是很好的方法名称,因为它们不匹配。因此,正如您所想,使用 setIsAvailable
或将 属性 更改为 available
并使用 setAvailable
/getAvailable
是正确的方法。
Vaadin Binder 使用 Java PropertyDescriptor 来查找 getters 和 setter。这只是在大写的 属性 名称之前添加 get
或 set
前缀的情况。
如果您使用布尔值,is
前缀也可以用于 getter,如 from the source code.
在那种情况下,您可以使用布尔值 属性 available
,然后使用 setAvailable
和 isAvailable
访问器方法。