Question

I have almost the same problem as this question: Property not readable on a inner class in a TreeModel

But the same solution seems not applicable.

I have a tree, and as I implemented my Entity, and my TreeModel, and they are working just fine, on my .zul file my "data" property isn't found on the treecell.

Here's some of the code:

-The structure implementation, that runs @AfterCompose:

 private void montarEstrutura(){

    Unidade ub1 = new Unidade();
    ub1.setParent(null);
    ub1.setNumero("NBase");
    ub1.setDescricao("DBase");

    Unidade ub2 = new Unidade();
    ub2.setParent(ub1);
    ub2.setNumero("N002");
    ub2.setDescricao("D002");

        Unidade ub4 = new Unidade();
        ub4.setParent(ub2);
        ub4.setNumero("N004");
        ub4.setDescricao("D004");

            Unidade ub6 = new Unidade();
            ub6.setParent(ub4);
            ub6.setNumero("N006");
            ub6.setDescricao("D006");

            Unidade ub7 = new Unidade();
            ub7.setParent(ub4);
            ub7.setNumero("N007");
            ub7.setDescricao("D007");

            Unidade ub8 = new Unidade();
            ub8.setParent(ub4);
            ub8.setNumero("N008");
            ub8.setDescricao("D008");

        Unidade ub5 = new Unidade();
        ub5.setParent(ub2);
        ub5.setNumero("N005");
        ub5.setDescricao("D005");

    Unidade ub3 = new Unidade();
    ub3.setParent(ub1);
    ub3.setNumero("N003");
    ub3.setDescricao("D003");


    List<Unidade> lub3 = new ArrayList<Unidade>();
    lub3.add(ub6);
    lub3.add(ub7);
    lub3.add(ub8);

    ub4.setUnidades(lub3);

    List<Unidade> lub2 = new ArrayList<Unidade>();
    lub2.add(ub4);
    lub2.add(ub5);
    ub2.setUnidades(lub2);

    List<Unidade> lub1 = new ArrayList<Unidade>();
    lub1.add(ub2);
    lub1.add(ub3);
    ub1.setUnidades(lub1);

    unidadeTreeModel = new UnidadeTreeModel(ub1);
    tree.setModel(unidadeTreeModel);

}

-The entity is pretty long, so I'll cut it:

@Entity
@Audited
public class Unidade extends AbstractSuseTools{

private String numero;
private String descricao;

    @OneToMany
private List<Unidade> unidades = new LinkedList<Unidade>();

    public String getNumero() {
    return numero;
}

public void setNumero(String numero) {
    this.numero = numero;
}

public String getDescricao() {
    return descricao;
}

public void setDescricao(String descricao) {
    this.descricao = descricao;
}
public List<Unidade> getUnidades() {
    return unidades;
}

public void setUnidades(List<Unidade> unidades) {
    this.unidades = unidades;
}
}

And here's the .zul file, that does not reads the property of the entity:

<div apply="org.zkoss.bind.BindComposer"
     viewModel="@id('vm') @init('br.com.simplesmenteuse.viewmodel.basico.OrganizacaoViewModel')"    >
   <tree id="tree" model="@load(vm.unidadeTreeModel)" selectedItem="@bind(vm.unidadeSelected)" >
        <treecols>
            <treecol width="100px" label="Editar" />
            <treecol width="100px" label="Excluir" />
            <treecol hflex="4" label="Número" />
            <treecol hflex="1" label="Nome" />
        </treecols>
        <template name="model">
            <treeitem>
                <treerow>
                    <treecell label="Editar"/>
                    <treecell label="Excluir"/>
                    <treecell label="@load(each.numero)"/>
                    <treecell label="@load(each.descricao)"/>
                </treerow>
            </treeitem>
        </template>
    </tree>

My TreeModel:

    public class UnidadeTreeModel extends AbstractTreeModel<Unidade> {
    /**
     *
     */
    private static final long serialVersionUID = 3854683349236034878L;

    public UnidadeTreeModel(Unidade unidade){
        super(unidade);
    }

    public boolean isLeaf(Unidade node) {
        return getLevel(node.toString()) >= 4; //at most 4 levels;
    }
    public Unidade getChild(Unidade parent, int index) {
        if(((Unidade)parent).getUnidades() != null && ((Unidade)parent).getUnidades().size() > index)
            return ((Unidade)parent).getUnidades().get(index);
        else
            return null;
    }
    public int getChildCount(Unidade parent) {
        return (((Unidade)parent).getUnidades() != null)?((Unidade)parent).getUnidades().size():0;
    }
    public int getIndexOfChild(Unidade parent, Unidade child) {
        for (int i  = 0; i<parent.getUnidades().size();i++) {
            if (child.equals(parent.getUnidades().get(i))) { return i;}
        }
        return -1; //or throw exception what you want.
    }
    private int getLevel(String data) {
        for (int i = -1, level = 0;; ++level)
            if ((i = data.indexOf('.', i + 1)) < 0)
                return level;
    }

};

The error:

Now it don't show any errors, just don't get the sub-levels of the object.

I don't really get how it's all done by the tree, so I can't get why it isn't been readable.

Was it helpful?

Solution

Just remove this data in your zul:

 <treecell label="@load(each.numero)"/>
   <treecell label="@load(each.nome)"/>

OTHER TIPS

Thats normal (cause you don't implemented the toString).

Now the problem is in your model(that was the test for). First thing I would like to have changed is this :

public class UnidadeTreeModel extends AbstractTreeModel<Object> {

to

public class UnidadeTreeModel extends AbstractTreeModel<Unidade> {

This will helps you already with all the castings and get a nicer clean code. Can you edit then the question with the new code of the model? That should help me with inspect the code faster.

Oke I did read your code a little intenser. I have a problem with this :

public int getIndexOfChild(Object parent, Object child) {
    String data = (String)child;
    int i = data.lastIndexOf('.');
    return Integer.parseInt(data.substring(i + 1));
}

What the ... are you doing there? String data will hold the adres (cause you don't have a toString)

Now try changing that to :

 public int getIndexOfChild(Unidade parent, Unidade child) {
    for (int i  = 0; i<parent.getUnidades().size();i++) {
        if (child.equals(parent.getUnidades().get(i))) { return i;}
    }
    return -1; //or throw exception what you want.
}

for the isLeaf (I don't know what about the 4th level but maybe you just can check with root?)

public boolean isLeaf(Unidade node) {
    return getRoot().equals(node);    
}

update latest question :

This I use to expand the tree after a button click :

private void doCollapseExpandAll(Component component, boolean aufklappen) {
    if (component instanceof Treeitem) {
        Treeitem treeitem = (Treeitem) component;
        treeitem.setOpen(aufklappen);
    }
    Collection<?> com = component.getChildren();
    if (com != null) {
        for (Iterator<?> iterator = com.iterator(); iterator.hasNext();) {
            doCollapseExpandAll((Component) iterator.next(), aufklappen);

        }
    }
}

public void fullyExpandTree(Component root){
    doCollapseExpandAll(root, true);
}

now you don't have to go all the way, just count to 4. I know you are smart enough to update that code ;).

Greetz chill.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top