【问题标题】:Vaadin ComboBox & LQCVaadin ComboBox & LQC
【发布时间】:2011-11-15 23:21:48
【问题描述】:

您能否提供数据绑定选择和 LazyQueryContainer 的完整示例?也欢迎与另一个容器绑定。 (LQC 中包含容器中的方法预期索引而不是项目 - 这是不同的行为)。

我无法使用简单的示例:

第一个表:货币(ID、代码、名称).... {1, USD, Dolar;2,EUR,Euro} 第二个表 ExchangeRate(ID, CcyFrom, CcyTo, Rate,ValidFrom) ... {1,1,2,1.515,2011/01/01;....}

我有一个容器,其中包含来自 Currency 的所有记录。我将其设置为 Select 的来源 ...

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

效果很好。

我有第二个容器,其中包含一些选择的 ExchangeRate。我将它绑定到表单,用 select 替换 TextField。 现在我想设置正确的值来选择 .... 但是 select.setValue(newValue) 不起作用当我调试它时,我发现 newValue 在容器中没有找到......我该怎么做呢?

不幸的是,vaadin 书中有几个示例不使用 LQC 或不使用容器来选择源(弹出窗口和值)。

【问题讨论】:

    标签: combobox containers vaadin


    【解决方案1】:

    我正在使用 Criteria Container(Lazy Query Container 的一个子类),但是由于 LQC 提供了索引和 ComboBox 期待该项目,这似乎与 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);
    

    【讨论】:

      【解决方案2】:

      即使这个帖子有点老了...... 我认为另一种解决方案是将核心 Vaadin 容器与分页一起使用。 这将确保客户设置的最大记录。 另一方面,我很好奇我是否可以使用传统的 dao 实现来使用 LazyQueryCONtainer,而不是通过实现 QUeryFactory 接口。 任何反馈都是有帮助的。

      【讨论】:

        【解决方案3】:

        SQLContainer

        您要求提供其他容器类型的示例。以下是SQLContainer 的示例(请参阅The Book Of Vaadin)。

        博客发布示例

        我在 Paul Reedman 的 2012-11 发布 Connecting a Vaadin SQL Container to a Combo Box 中发现了这个出色而简单的示例。有关详细信息,请参阅发布。下面是他的代码sn-ps。我添加或修改了一些 cmets。

        代码片段

        创建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);
        

        【讨论】:

          【解决方案4】:

          当您开始扩展用户时,将几千个项目添加到 ComboBox 并不高效。请记住,所有这些都隐藏在HttpSession 中。如果您不是很小心,您的内存消耗将会激增。

          我最近对使用IndexedContainerBeanItemContainer 的应用程序进行了一个简单的测试,并且消耗的内存量非常不同。被测试的BeanItem 是一个具有许多关系和属性的持久 JPA 实体。对于组合框,我们实际上只需要两个属性:id 和 name。

          BeanItemContainer 每个用户消耗 50MB,而IndexedContainer 每个用户消耗 2MB。因此,如您所见,如果您不注意会话中存储的信息类型,它将无法很好地扩展。恕我直言,即使 2MB 也不能令人满意,更好的设计会使用惰性查询容器。

          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 或 IBM JDK 的 'com.ibm.jvm.Dump.HeapDump()' 以编程方式转储堆。

          2MB 堆消耗(序列化:0.33 MB)与 50MB(序列化:13.12MB)

          YMMV 取决于您运行的平台/JDK。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-06-04
            • 2023-03-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多