myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stephen Friedrich <trini...@eekboom.com>
Subject RE: [TRINIDAD] Implementation of Treemodel for tr:tree Example or a Howto?
Date Mon, 26 May 2008 11:53:26 GMT
Well, there is of course the section in the developer guide:
   http://myfaces.apache.org/trinidad/devguide/tree.html
but that's, well, let's say it could be improved.
The highlights are how it tries to explain a tree model by pointing to the table docs.
Also the javadocs are strangely written from the perspective of internal Trinidad usage rather
than the end user.

Anyway - after fiddling for a while I wrote a base class for tree nodes with a parent and
children, plus a custom trinidad tree model that is based on this natural concept rather than
bending and breaking tables until they look like a tree.

See the classes below. You can use them for reference. If you want to use the code directly,
then
you'll have to figure out how to get a reference to an EntityManager (or retrieve child nodes
in another way). (I am using a seam with a seammanaged persistence context.)

---------------------------------------------------------------------------------------------------

package com.acme.foo;

import javax.persistence.EntityManager;
import java.io.Serializable;
import java.util.List;

public abstract class MyTreeNode implements Serializable {
    private final MyTreeNode parentNode;
    private final String label;
    private final boolean isLeaf;

    private List<MyTreeNode> childNodes;

    protected MyTreeNode(MyTreeNode parentNode, String label, boolean leaf) {
        this.parentNode = parentNode;
        isLeaf = leaf;
        this.label = label;
    }

    public final String getLabel() {
        return label;
    }

    public final MyTreeNode getParent() {
        return parentNode;
    }

    public boolean isLeaf() {
        return isLeaf;
    }

    public final List<? extends MyTreeNode> getChildren(EntityManager entityManager)
{
        if (childNodes == null) {
            childNodes = queryChildren(entityManager);
        }
        return childNodes;
    }

    protected abstract List<MyTreeNode> queryChildren(EntityManager entityManager);
}

---------------------------------------------------------------------------------------------------

package com.acme.foo;

import org.apache.myfaces.trinidad.model.TreeModel;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.persistence.ManagedPersistenceContext;

import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.transaction.SystemException;
import java.io.Serializable;
import java.util.List;

public class MyTreeModel extends TreeModel implements Serializable {
    private Object parentNode;

    private List childNodes;

    private int selectedNodeIndex;

    private final MyTreeNode rootNode;

    public MyTreeModel(MyTreeNode rootNode) {
        this.rootNode = rootNode;
        childNodes = rootNode.getChildren(getEntityManager());
        selectedNodeIndex = -1;
    }

    public Object getParentNode(Object o) {
        if (o == null) {
            return null;
        }
        return ((MyTreeNode) o).getParent();
    }

    private List getChildNodes(Object o) {
        if (o == null) {
            return rootNode.getChildren(getEntityManager());
        }
        return ((MyTreeNode) o).getChildren(getEntityManager());
    }

    @Override
    public boolean isContainer() {
        if (selectedNodeIndex == -1) {
            return false;
        }

        return !((MyTreeNode) childNodes.get(selectedNodeIndex)).isLeaf();
    }

    /**
     * @return true, iff the current node actually has NO children
     */
    @Override
    public boolean isContainerEmpty() {
        if (selectedNodeIndex == -1) {
            return true;
        }
        return ((MyTreeNode)childNodes.get(selectedNodeIndex)).isLeaf();
    }

    @Override
    public void enterContainer() {
        if (selectedNodeIndex == -1) {
            return;
        }

        parentNode = childNodes.get(selectedNodeIndex);
        childNodes = getChildNodes(parentNode);
        selectedNodeIndex = childNodes.isEmpty() ? -1 : 0;
    }

    @Override
    public void exitContainer() {
        Object selectedNode = parentNode;
        parentNode = getParentNode(parentNode);
        childNodes = getChildNodes(parentNode);
        selectedNodeIndex = findListElementIndex(childNodes, selectedNode);
    }

    @Override
    public Object getContainerRowKey(Object childRowKey) {
        if (childRowKey == null) {
            return null;
        }
        return getParentNode(childRowKey);
    }

    @Override
    public Object getRowKey() {
        if (selectedNodeIndex == -1) {
            return null;
        }
        return childNodes.get(selectedNodeIndex);
    }

    @Override
    public void setRowKey(Object key) {
        parentNode = getParentNode(key);
        childNodes = getChildNodes(parentNode);
        selectedNodeIndex = findListElementIndex(childNodes, key);
    }

    @Override
    public int getRowCount() {
        if (childNodes == null) {
            return 0;
        }
        return childNodes.size();
    }

    @Override
    public Object getRowData() {
        if (selectedNodeIndex == -1) {
            return null;
        }
        return childNodes.get(selectedNodeIndex);
    }

    private static int findListElementIndex(List list, Object object) {
        if (list == null || object == null) {
            return -1;
        }

        int index = list.indexOf(object);
        return index;
    }

    @Override
    public int getRowIndex() {
        return selectedNodeIndex;
    }

    @Override
    public Object getWrappedData() {
        // This method is never to be called
        return null;
    }

    @Override
    public void setWrappedData(Object data) {
    }

    @Override
    public boolean isRowAvailable() {
        boolean result = childNodes != null && selectedNodeIndex >= 0 &&
selectedNodeIndex < childNodes.size();

        return result;
    }

    @Override
    public void setRowIndex(int rowIndex) {
        if (childNodes == null) {
            return;
        }
        if (rowIndex < 0 || rowIndex >= childNodes.size()) {
            selectedNodeIndex = -1;
            return;
        }

        selectedNodeIndex = rowIndex;
    }

    protected EntityManager getEntityManager() {
        ManagedPersistenceContext c = (ManagedPersistenceContext) Contexts.getConversationContext().get("entityManager");
        try {
            EntityManager entityManager = c.getEntityManager();
            return entityManager;
        }
        catch (NamingException e) {
            throw new RuntimeException("Failed to retrieve EntityManager from conversation
context", e);
        }
        catch (SystemException e) {
            throw new RuntimeException("Failed to retrieve EntityManager from conversation
context", e);
        }
    }
}

 

Hi @ all,


 
does someone know or have a running example where heimplemented his own treemodel? Or a example
/ javadoc where the whole idea howthe model should be implemented is explained?

I am implementing my own treemodel. So I inherit fromTreemodel and implement all the abstract
methods.

In my model I have a department which hassubdepartments and each subdepartment can also contain
subdepartments …

The model seems to work but the PPR seem not to work.

When I open the node in the UI then just the firstchild is shown. After calling refresh everything
(the whole tree) is shown.

What could be the reason?


 
Thank a lot of.


 
Kind regards

Martin

 
Mime
View raw message