【问题标题】:Too much items in a Vaadin TreeVaadin 树中的物品过多
【发布时间】:2013-10-19 02:50:23
【问题描述】:

我正在使用 Vaadin 构建一个 Web 应用程序,其中一个功能需要一个树来显示元素,问题是这个树加载了高达 (40K) 甚至更多的项目。

在数千个项目的级别上,Vaadin 树是可以接受的,但现在不是,它正在减慢 Web 浏览器中的所有内容。

我想到的是对 web 服务器和 web 客户端之间的负载进行分页,并显示几个在用户滚动树时更新的项目,问题是我不知道从哪里开始,即使这是否适用.

这是一个好方法吗?有更好的吗? 为一张桌子放弃一棵树不是解决方案,客户不想这样做。

【问题讨论】:

    标签: java vaadin


    【解决方案1】:

    在这种情况下,我建议您使用TreeTable 而不是Tree。它从服务器延迟加载行到客户端,因此不会降低浏览器的速度。

    【讨论】:

      【解决方案2】:

      您可以在扩展树的节点时通过动态添加子节点来延迟加载树的内容。我多次使用的方法的基本思想是,

      final Tree tree = new Tree();
      //get the top level collection of entities
              Collection<MyEntity> myEntitiesCategories = findEntities(MyEntity.class);//findEntities is one of your method that retrieves entities from a datasource
              for (MyEntity myEntity : myEntitiesCategories) {
                  tree.addItem(myEntity);
              }
              tree.addListener(new Tree.ExpandListener() {
      
                  @Override
                  public void nodeExpand(ExpandEvent event) {
                      MyEntity myEntityCategory = (MyEntity) event.getItemId();
                      Collection<MyEntity> myEntities = myEntityCategory.getChildrenMyEntities();
                      for (MyEntity myEntity : myEntities) {
                          tree.addItem(myEntity);
                          tree.setParent(myEntity, myEntityCategory);
                          tree.setChildrenAllowed(myEntity, false);//the boolean value could also be true, it depends on whether it can have children or not
                      }
                  }
              });
      

      【讨论】:

        【解决方案3】:

        据我所知Tree 组件不支持内置延迟加载(这对我们所有人来说都是最方便的)。

        一种方法是:

        Here 你可以找到一个使用 Tree.ExpandListener 的示例。
        Here 你可以找到一个 Collapsible 容器的示例实现。

        希望对你有帮助。

        【讨论】:

          【解决方案4】:

          尽管在 Vaadin 文档中它说 Tree 的延迟加载是 not supported,但我还是设法实现了以下 延迟加载 Hierarchical 接口。

          将所有元素存储在本地结构中非常重要(在我的情况下是HashMaphierarchy),不要多次读取元素,这是行不通的。我认为是因为 Vaadin 不使用 equals()hashCode()

          import java.util.Collection;
          import java.util.Collections;
          import java.util.HashMap;
          import java.util.List;
          import java.util.Map;
          
          import com.softmodeler.common.CommonPlugin;
          import com.softmodeler.model.OutputNode;
          import com.softmodeler.service.IViewService;
          import com.vaadin.data.Container.Hierarchical;
          import com.vaadin.data.Item;
          import com.vaadin.data.Property;
          import com.vaadin.data.util.BeanItem;
          
          /**
           * @author Flavio Donzé
           * @version 1.0
           */
          public class OutputNodeHierachical implements Hierarchical {
              private static final long serialVersionUID = 8289589835030184018L;
          
              /** the view service */
              private IViewService service = CommonPlugin.getService(IViewService.class);
          
              /** collection of all root nodes */
              private List<OutputNode> rootNodes = null;
              /** parent=>children mapping */
              private Map<OutputNode, List<OutputNode>> hierarchy = new HashMap<>();
          
              /**
               * constructor
               *
               * @param rootNodes collection of all root nodes
               */
              public OutputNodeHierachical(List<OutputNode> rootNodes) {
                  this.rootNodes = Collections.unmodifiableList(rootNodes);
          
                  addToHierarchy(rootNodes);
              }
          
              @Override
              public Collection<?> getChildren(Object itemId) {
                  try {
                      List<OutputNode> children = hierarchy.get(itemId);
                      if (children == null) {
                          OutputNode node = (OutputNode) itemId;
                          children = service.getChildren(node.getNodeId(), false);
          
                          hierarchy.put(node, children);
          
                          // add children to hierarchy, their children will be added on click
                          addToHierarchy(children);
                      }
                      return children;
                  } catch (Exception e) {
                      VaadinUtil.handleException(e);
                  }
                  return null;
              }
          
              /**
               * add each element to the hierarchy without their children hierarchy(child=>null)
               *
               * @param children elements to add
               */
              private void addToHierarchy(List<OutputNode> children) {
                  for (OutputNode child : children) {
                      hierarchy.put(child, null);
                  }
              }
          
              @Override
              public boolean areChildrenAllowed(Object itemId) {
                  return !((OutputNode) itemId).getChilds().isEmpty();
              }
          
              @Override
              public boolean hasChildren(Object itemId) {
                  return !((OutputNode) itemId).getChilds().isEmpty();
              }
          
              @Override
              public Object getParent(Object itemId) {
                  String parentId = ((OutputNode) itemId).getParentId();
                  for (OutputNode node : hierarchy.keySet()) {
                      if (node.getNodeId().equals(parentId)) {
                          return node;
                      }
                  }
                  return null;
              }
          
              @Override
              public Collection<?> rootItemIds() {
                  return rootNodes;
              }
          
              @Override
              public boolean isRoot(Object itemId) {
                  return rootNodes.contains(itemId);
              }
          
              @Override
              public Item getItem(Object itemId) {
                  return new BeanItem<OutputNode>((OutputNode) itemId);
              }
          
              @Override
              public boolean containsId(Object itemId) {
                  return hierarchy.containsKey(itemId);
              }
          
              @Override
              public Collection<?> getItemIds() {
                  return hierarchy.keySet();
              }
          
              @Override
              public int size() {
                  return hierarchy.size();
              }
          
              @Override
              public boolean setParent(Object itemId, Object newParentId) throws UnsupportedOperationException {
                  throw new UnsupportedOperationException();
              }
          
              @Override
              public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed) throws UnsupportedOperationException {
                  throw new UnsupportedOperationException();
              }
          
              @Override
              public Item addItem(Object itemId) throws UnsupportedOperationException {
                  throw new UnsupportedOperationException();
              }
          
              @Override
              public Object addItem() throws UnsupportedOperationException {
                  throw new UnsupportedOperationException();
              }
          
              @Override
              public boolean removeItem(Object itemId) throws UnsupportedOperationException {
                  throw new UnsupportedOperationException();
              }
          
              @Override
              public boolean removeAllItems() throws UnsupportedOperationException {
                  throw new UnsupportedOperationException();
              }
          
              @Override
              public Class<?> getType(Object propertyId) {
                  throw new UnsupportedOperationException();
              }
          
              @Override
              public Collection<?> getContainerPropertyIds() {
                  throw new UnsupportedOperationException();
              }
          
              @Override
              public Property<?> getContainerProperty(Object itemId, Object propertyId) {
                  throw new UnsupportedOperationException();
              }
          
              @Override
              public boolean addContainerProperty(Object propertyId, Class<?> type, Object defaultValue) throws UnsupportedOperationException {
                  throw new UnsupportedOperationException();
              }
          
              @Override
              public boolean removeContainerProperty(Object propertyId) throws UnsupportedOperationException {
                  throw new UnsupportedOperationException();
              }
          
          }
          

          像这样将容器添加到Tree

          OutputNodeHierachical dataSource = new OutputNodeHierachical(rootNodes);
          
          Tree mainTree = new Tree();
          mainTree.setSizeFull();
          mainTree.setContainerDataSource(dataSource);
          mainTree.addItemClickListener(new ItemClickListener() {
              private static final long serialVersionUID = -413371711541672605L;
          
              @Override
              public void itemClick(ItemClickEvent event) {
                  OutputNode node = (OutputNode) event.getItemId();
                  openObject(node.getObjectId());
              }
          });
          


          我希望这个示例对其他人有所帮助,因为我在互联网上没有找到真实的示例。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-02
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多