проблемы с ComboBox в форме

Есть вот такой код


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:

@Override
    protected void setInternalValue(Object newValue)
    {
      if (newValue instanceof Integer) {
        newValue = new RowId(new Object[]{ newValue });
      }
      super.setInternalValue(newValue);
    }

И все работало нормально. Надо признать, что SqlContainer был как адд-он, а не встроенный, да и форма была чуть другой. Пожалуйста, дайте знать, если не поможет.

cheers,
sasha

Спасибо, вечером обязательно проверю…
Но я не могу понять в чем причина бага и что мешает отобразить выбранное значение?

Не помогло…
Куда копать не знаю :frowning:

Здравствуйте,

Причина бага в том, что Вы связываете форму с 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 во многом пересмотрен, в особенности что касается конвертации.

У меня такое чувство что дело не только в конвертации (хотя и в ней тоже).
В setFormFieldFactory сделал так:

		    	            	f = createUser;
		    	            	createUser.setPropertyDataSource(new PropertyTranslator(item.getItemProperty(propertyId)){

									@Override
									public Object translateFromDatasource(Object arg0) {
										// TODO Auto-generated method stub
										return new RowId(new Object[]{ arg0 });
									}

									@Override
									public Object translateToDatasource(Object arg0) throws Exception {
										// TODO Auto-generated method stub
										return arg0;
									}
		    	            		
		    	            	});

Вроде сделал все верно, но результата никакого.

Вот
здесь
еще один способ описан.
Перегрузил в форме метод

		 @Override
		    public void setItemDataSource(Item newDataSource) {
		        if (newDataSource != null) {
		        	super.setItemDataSource(newDataSource);
		        	setReadOnly(false);
		        	if (newDataSource.getItemProperty("PROJECT_CREATEUSER").getValue() != null) {
		        		createUser.select(new RowId(new Object[] { newDataSource
		        	                .getItemProperty("PROJECT_CREATEUSER").getValue() }));
		        	} else {
		        		createUser.select(createUser.getItemIds().iterator().next());
		        	}
		        	
		        } else {
		            super.setItemDataSource(null);
		        }
		    }

Вроде все просто но результата никакого. Мне кажется я чего-то не делаю или делаю лишние.

Нашел несколько решений. Они некрасивые, но рабочие.
1.


private class ComboBox1 extends ComboBox{
		 Property dataSource=null;
		 
		 @Override
		 protected void setInternalValue(Object newValue)
		    {
		     if (newValue==null) 
		    	 if (dataSource!=null) {
		    		 dataSource.setValue(newValue);
		    		 return; 
		    	 }
			 if (!(newValue instanceof RowId)) {
		        newValue = new RowId(new Object[]{ newValue });
		      }
		      super.setInternalValue(newValue);
		      dataSource.setValue(newValue);
		    }
		 
		 @Override   
		 public void setPropertyDataSource(Property newDataSource) {
			 	dataSource=newDataSource;
				if (dataSource!=null) setInternalValue(dataSource.getValue());
				super.setPropertyDataSource(null);
		 }
}

private class ComboBox1 extends ComboBox{
		 @Override   
		 public void setContainerDataSource(Container newDataSource) {
			 Object lid=null; 
			 if (newDataSource instanceof SQLContainer) { 
					 Iterator iterator = newDataSource.getItemIds().iterator();
					   	while (iterator.hasNext()) {
					   		Object id=iterator.next();
					   		if (id instanceof RowId)  
					   			lid=((RowId) id).getId()[0]
;
					   		else
					   			lid=id;
					   		this.addItem(lid);
						   	this.setItemCaption(lid,newDataSource.getContainerProperty(id, this.getItemCaptionPropertyId()).getValue().toString());
					   	}
					   	this.setItemCaptionMode(Select.ITEM_CAPTION_MODE_EXPLICIT);
			  }
			  else
				  super.setContainerDataSource(newDataSource);
		 }
}