public class ProjectLayout extends VerticalLayout {
private Table projectList = new Table();
private projectForm projectEditor=null;
private SQLContainer container = null;
private SQLContainer containerusr = null;
...
public ProjectLayout ()
{
try {
TableQuery tq = new TableQuery("PROJECT", SaribApplication.getInstance().connectionPool);
tq.setVersionColumn("PROJECT_ID");
container = new SQLContainer(tq);
TableQuery usr = new TableQuery("USR", SaribApplication.getInstance().connectionPool);
usr.setVersionColumn("USR_ID");
containerusr = new SQLContainer(usr);
} catch (SQLException e) {
SaribApplication.getInstance().showError("Could not create an instance of SQLContainer!");
e.printStackTrace();
}
//Создаем свою форму для редактирования
projectEditor=new projectForm();
projectEditor.setSizeFull();
projectEditor.setImmediate(true);
projectList.setContainerDataSource(container);
projectList.setVisibleColumns(new String[] {"PROJECT_NAME","PROJECT_CREATEDATE","PROJECT_DESCRIPTION"});
projectList.setColumnHeaders(new String[]{"Проект","Дата создания","Описание"});
projectList.setSelectable(true);
projectList.setImmediate(true);
projectList.addListener(new Property.ValueChangeListener() {
public void valueChange(ValueChangeEvent event) {
Object id = projectList.getValue();
if (id instanceof Integer) {
try {
container.rollback();
} catch (UnsupportedOperationException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
projectEditor.setItemDataSource(id == null ? null : projectList.getItem(id));
}
});
...
private class projectForm extends Form{
private ComboBox createUser=new ComboBox("Автор");
public projectForm() {
createUser.setItemCaptionPropertyId("USR_NAME");
createUser.setContainerDataSource(containerusr);
this.setFormFieldFactory(new FormFieldFactory() {
public Field createField(Item item, Object propertyId, Component uiContext) {
Field f = null;
if ("PROJECT_NAME".equals(propertyId)) {
f = new TextField("Имя проекта");
}
else if ("PROJECT_CREATEDATE".equals(propertyId)) {
f = new PopupDateField("Время создания");
PopupDateField df = (PopupDateField) f;
}
else if ("PROJECT_CREATEUSER".equals(propertyId)) {
f = createUser;
}
else if ("PROJECT_DESCRIPTION".equals(propertyId)) {
f = new TextArea("Описание");
f.setWidth(500);
f.setHeight(100);
}
return f;
}
});
}
}
проблема заключается в том, что при связывании ComboBox с Item, ComboBox не отображает выбранное значение из БД.
Если выполнить
projectEditor.createUser.setValue(new RowId(new Object {1})) или projectEditor.getField(“PROJECT_CREATEUSER”).setValue(new RowId(new Object
{1}))
в базу запишется установленное значение, но ComboBox опять не чего не показывает.
При этом если ComboBox не связан с Item, то значение без проблем выбирается из списка.
Здравствуйте,
Где-то с полгода назад я решал такую проблему следующим образом:
Исходная ситуация - у нас форма, представляющая некую запись из таблицы бд, в ней - ComboBox, содержащий элементы из сопряженной таблицы, связанной с первой внешним ключом. В целом делал как Вы, только в классе ComboBox’a перегружал метод setInternalValue:
И все работало нормально. Надо признать, что SqlContainer был как адд-он, а не встроенный, да и форма была чуть другой. Пожалуйста, дайте знать, если не поможет.
Причина бага в том, что Вы связываете форму с Item’ом через Vaadin Data APi, в то же время пытаясь напрямую задавать значения для Combobox. Получится или нет -зависит от того, где конкретно вы пытаетесь задать значение напрямую. То, что я посоветовал - должно сработать, но только в одну сторону - на отображение формы, изменить что либо вряд ли вышло б. Я бы в конечном итоге Вам посоветовал обратить внимание на CustomField и в частности на вот
это .
В этом файле показано как конвертировать значения для bean’ов и для элементов из JPAContainer. Вариант BeanFieldPropertyConverter в Вашем случае должен быть гораздо проще (никакой рефлексии по крайней мере). Другой вариант -
этот адд-он , который делает то, что вам нужно.
Значение из списка не выбирается не только при изменении значения напрямую в Combobox,
но и когда форма на которой находится Combobox связывается с Item.
Ну это вытекает из факта, что у вас в первом контейнере внешний ключ имеет тип Integer, второй контейнер (который снабжает ComboBox) - имеет RowId в качетсве id. Когда Вы привязываете itеm к форме - делается попытка задать полям значения свойств (property) из item. То есть вашему ComboBox пытается задаться значение int, которого заведомо нет в его контейнере. Попытка перегрузить setValue или setInternalValue - может помочь (если очень постараться), но опять таки повторюсь - будет работать лишь в одну сторону. API в PropertyTranslator или CustomField обеспечат Вас двусторонней конвертацией. Да, этот процесс мог бы выглядеть и попроще, в Vaadin 7 - так и будет, Data API во многом пересмотрен, в особенности что касается конвертации.