Vaadin ComboBox и LQC

Можете ли вы привести полный пример выбора привязки данных и LazyQueryContainer? Связывание с другим контейнером тоже приветствуется. (LQC содержит ожидаемый индекс метода в контейнере, а не элемент - это другое поведение).

Я не могу заставить работать простой пример:

Первая таблица: Валюта (ID, Код, Имя) .... {1, USD, Долар; 2, EUR, Евро} Вторая таблица ExchangeRate (ID, CcyFrom, CcyTo, Rate, ValidFrom) ... {1,1, 2,1.515,2011/01/01;....}

У меня есть один контейнер, который содержит все записи из валюты. Я установил его как источник Select...

Select result = new Select("Select currency", currencies);        result.setItemCaptionMode(Select.ITEM_CAPTION_MODE_PROPERTY);        result.setItemCaptionPropertyId("code");

Это работает нормально.

У меня есть второй контейнер, который содержит некоторый выбор ExchangeRate. Я привязываю его к форме, заменяю TextField на select. Теперь я хочу установить правильное значение для выбора .... но select.setValue (newValue) не работает. Когда я отлаживаю его, я обнаружил, что новое значение не найдено в контейнере ... как я могу сделать это правильно?

В книге vaadin есть несколько примеров, к сожалению, они не используют LQC или не используют контейнер для выбора источника (всплывающее окно и значение).


person Vlada    schedule 13.09.2011    source источник


Ответы (4)


Я использую Criteria Container (подкласс Lazy Query Container), однако кажется, что это и ComboBox несовместимы из-за того, что LQC предоставляет индекс, а ComboBox ожидает элемент — см. http://vaadin.com/forum///message_boards/view_message/254510

Обходной путь, который я использовал, — это просто загрузить все объекты в BeanItemContainer, как показано ниже. В этом случае я имею дело только с несколькими тысячами записей, и это удивительно эффективно.

  BeanItemContainer<Contact> bic = new BeanItemContainer<Contact>(Contact.class);
  List<Contact> contacts = dao.all(Contact.class, Contact_.lastName);
  bic.addAll(contacts);

  ComboBox cb = new ComboBox("Please select contact");
  cb.setContainerDataSource(bic);
person Will    schedule 16.09.2011

даже этот поток довольно старый ... я думаю, что другим решением было бы использование основных контейнеров Vaadin с разбиением на страницы. это обеспечит максимальное количество записей, созданных клиентом. С другой стороны, мне любопытно, могу ли я использовать LazyQueryCOntainer, используя устаревшую реализацию dao, а не реализуя интерфейс QUeryFactory. Любая обратная связь полезна.

person claudiu cosar    schedule 31.01.2013

SQLContainer

Вы просили другие примеры контейнерного типа. Ниже приведен пример для SQLContainer (см. Книга Ваадина).

Пример взят из публикации в блоге

Я нашел этот отличный и простой пример в публикации 2012–2011 годов: Подключение контейнера SQL Vaadin к полю со списком, автор Пол Ридман. Подробности смотрите в публикации. Ниже приведены фрагменты его кода. Некоторые комментарии были добавлены или изменены мной.

Фрагменты кода

Создайте метод loadSuburbs для возврата источника данных контейнера. Этот метод создает такой SQLContainer…

TableQuery q = new TableQuery("suburb", connectionPool);
suburbContainer = new SQLContainer(q);

Вызовите этот метод, передав результат в поле со списком.

ComboBox suburbCB = new ComboBox();
suburbCB.addItem("");
suburbCB.setCaption("Filter by Suburb");
suburbCB.setContainerDataSource(app.getDatabase().loadSuburbs());  // Hook-up SQLContainer.

// Specify which Property (field) in the SQLContainer to display as content in the ComboBox.
// If omitted, the 'id' Property appears as content.
suburbCB.setItemCaptionPropertyId("name");
suburbCB.setItemCaptionMode(AbstractSelect.ITEM_CAPTION_MODE_PROPERTY);

// Set a reasonable width
suburbCB.setWidth(350, UNITS_PIXELS);

// Set the appropriate filtering mode for this example, allowing user to type-ahead.
suburbCB.setFilteringMode(Filtering.FILTERINGMODE_STARTSWITH);
suburbCB.setImmediate(true);
person Basil Bourque    schedule 30.12.2014

Добавление нескольких тысяч элементов в ComboBox НЕ эффективно, когда вы начинаете масштабировать пользователей. Помните, что все это спрятано в HttpSession. Потребление памяти резко возрастет, если вы не будете очень осторожны.

Недавно я провел простой тест профилирования приложения, которое использовало IndexedContainer и BeanItemContainer, и объем потребляемой памяти был ОЧЕНЬ разным. Тестируемый BeanItem был постоянным объектом JPA со многими отношениями и свойствами. Для поля со списком нам действительно нужны только два свойства: id и имя.

BeanItemContainer потребляет 50 МБ на пользователя против 2 МБ на пользователя для IndexedContainer. Итак, как вы можете видеть, масштабирование будет не очень хорошим, если вы не будете осторожны с тем, какой тип информации хранится в сеансе. ИМХО, даже 2 МБ недостаточно, и вместо этого лучше использовать контейнер ленивых запросов.

BeanItemContainer необходимо создать копию каждого поля/ассоциации, независимо от того, есть ли в нем данные или нет, что объясняет большую часть разницы в памяти. Плагин Eclipse Memory Analyzer очень удобен для анализа дампов кучи :)

class EditViewTest {

private ComboBox comboBox

@Test
void serialize() {
    BeanItemContainer<Organization> container = new BeanItemContainer<Organization>(Organization)
    container.addAll(getAllOrgs().sort({ a, b -> a.name <=> b.name }))

    comboBox = new ComboBox('Organization', container)
    comboBox.setItemCaptionMode(Select.ITEM_CAPTION_MODE_PROPERTY)
    comboBox.setItemCaptionPropertyId("name")

    long fileLength
    def temp = File.createTempFile('orgs','.ser')
    try {
        temp.withObjectOutputStream { out ->
            out << comboBox
        }
        fileLength = temp.length()
    }
    finally {
        temp.delete()
    }

    println fileLength / 1024 / 1024
    HeapDumper.dumpHeap('serialize.bin', true)

    Thread.sleep(10000L)
}

@Test
void serialize2() {
    comboBox = new ComboBox()
    getAllOrgs().each { Organization org ->
        comboBox.addItem(org.id)
        comboBox.setItemCaption(org.id, org.name)
    }

    long fileLength
    def temp = File.createTempFile('orgs','.ser')
    try {
        temp.withObjectOutputStream { out ->
            out << comboBox
        }
        fileLength = temp.length()
    }
    finally {
        temp.delete()
    }

    println fileLength / 1024 / 1024
    HeapDumper.dumpHeap('serialize2.bin', true)

    Thread.sleep(10000L)
}

private List getAllOrgs() {
    def orgs = []
    3197.times {
        orgs << new Organization(id: UUID.randomUUID().toString(), 
            company: new Company(name: RandomStringUtils.randomAscii(24)))
    }
    return orgs
}
}

Вы можете использовать HotSpotDiagnosticMXBean для программного дампа кучи с Oracle JVM или 'com.ibm.jvm.Dump.HeapDump()' для IBM JDK.

Потребление кучи 2 МБ (последовательно: 0,33 МБ) против 50 МБ (последовательно: 13,12 МБ)

YMMV в зависимости от того, какую платформу/JDK вы используете.

person Kirk Rasmussen    schedule 25.05.2012