Java Vaadin树中的项目太多

Java Vaadin树中的项目太多,java,vaadin,Java,Vaadin,我正在使用Vaadin构建一个web应用程序,其中一个特性需要一个树来显示元素,问题是这个树最多加载40K个项目,甚至更多 在几千项的水平上,Vaadin树是可以接受的,但现在不行,它正在减缓web浏览器中的一切 我想到的是在web服务器和web客户端之间对负载进行分页,并显示一些在用户滚动树时更新的项目,问题是我不知道从哪里开始,即使这是否适用 这是一个好方法吗?有更好的吗? 为表放弃树不是一个解决方案,客户不希望。据我所知,树组件不支持内置的延迟加载(这对我们所有人来说都是最方便的) 一种办

我正在使用Vaadin构建一个web应用程序,其中一个特性需要一个树来显示元素,问题是这个树最多加载40K个项目,甚至更多

在几千项的水平上,Vaadin树是可以接受的,但现在不行,它正在减缓web浏览器中的一切

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

这是一个好方法吗?有更好的吗?
为表放弃树不是一个解决方案,客户不希望。

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

一种办法是:

  • 实现您自己的容器作为数据源
  • 使用展开树节点后,从容器中惰性加载树元素
您可以找到一个使用Tree.ExpandListener的示例。
您可以找到可折叠容器的示例实现


我希望它能有所帮助。

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

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

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
                }
            }
        });
final Tree=new Tree();
//获取顶级实体集合
集合MyEntityCategories=findentials(MyEntity.class)//findEntities是从数据源检索实体的方法之一
对于(MyEntity MyEntity:myEntitiesCategories){
树。addItem(myEntity);
}
addListener(new tree.ExpandListener()){
@凌驾
public void nodeExpand(ExpandEvent事件){
MyEntity myEntityCategory=(MyEntity)事件。getItemId();
集合myEntities=myEntityCategory.getChildrenMyEntities();
for(MyEntity MyEntity:myEntities){
树。addItem(myEntity);
setParent(myEntity,myEntityCategory);
tree.setChildrenAllowed(myEntity,false);//布尔值也可以为true,这取决于它是否可以有子级
}
}
});

即使在Vaadin文档中,它说树的延迟加载是,我还是设法实现了以下延迟加载
分层接口。

将所有元素存储在本地结构中非常重要(在我的示例中是
HashMap
层次结构中),不要多次读取元素,这不起作用。我想是因为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();
    }

}
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());
    }
});