0

setSelectable(false) didn't work in TreeitemRenderer

asked 2024-02-27 16:32:54 +0800

ynizzz gravatar image ynizzz
3 1

Hi all,

I'm using treeitemrender of ZK 9 to load the data. In some conditions, the items should not be selectable. I tried to use the method setSelectable(false) of Treeitem.class but it didn't work.

Another method setDisabled(true) can work but that's not the best choice for me.

Here is my codes to reproduce it: (In fact I output it on zkfiddle, but I cannot paste the link here. Maybe you can go there then search the key word 'TreeitemRenderer' to find it.)

ZUL:

<zk>
    <window id="queryFoodWindow"
            apply="org.zkoss.bind.BindComposer"
            viewModel="@id('vm') @init('pkg$.FoodViewModel')">
    <tree checkmark="true" model="@load(vm.foodTreeModel)" width="1000px" itemRenderer="@load(vm.foodTreeitemRenderer)">
        <treecols>
            <treecol width="600px" label="Name"/>
            <treecol label="Color"/>
            <treecol label="Quantity"/>
        </treecols>
    </tree>
    </window>
</zk>

VM:

import java.util.ArrayList;
import java.util.List;

import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zul.DefaultTreeModel;
import org.zkoss.zul.DefaultTreeNode;
import org.zkoss.zul.Tree;
import org.zkoss.zul.TreeNode;

public class FoodViewModel {

    private DefaultTreeModel<Food> foodTreeModel;
    private FoodTreeitemRenderer foodTreeitemRenderer;
    private Tree tree;

    @Init
    public void init() {
        List<TreeNode<Food>> rootNodes = createFoodData();
        DefaultTreeNode<Food> root = new DefaultTreeNode<>(null, rootNodes);

        foodTreeModel = new DefaultTreeModel<>(root);
        foodTreeitemRenderer = new FoodTreeitemRenderer();
        tree = new Tree();
        tree.setModel(foodTreeModel);
        tree.setItemRenderer(foodTreeitemRenderer);
    }

    public DefaultTreeModel<Food> getFoodTreeModel() {
        return foodTreeModel;
    }

    private List<TreeNode<Food>> createFoodData() {
        List<TreeNode<Food>> rootNodes = new ArrayList<>();

        DefaultTreeNode<Food> nodes = new DefaultTreeNode<>(new Food("Apple", "Red", 5), new ArrayList<>());
        DefaultTreeNode<Food> childNode1 = new DefaultTreeNode<>(new Food("Apple1", "Red1", 3), false);
        nodes.add(childNode1);
        nodes.add(new DefaultTreeNode<>(new Food("Apple2", "Red2", 3)));

        TreeNode<Food> node2 = new DefaultTreeNode<>(new Food("Banana", "Yellow", 3));
        TreeNode<Food> node3 = new DefaultTreeNode<>(new Food("Orange", "Orange", 4));

        rootNodes.add(nodes);
        rootNodes.add(node2);
        rootNodes.add(node3);

        return rootNodes;
    }

    public void setFoodTreeModel(DefaultTreeModel<Food> foodTreeModel) {
        this.foodTreeModel = foodTreeModel;
    }

    public FoodTreeitemRenderer getFoodTreeitemRenderer() {
        return foodTreeitemRenderer;
    }

    public void setFoodTreeitemRenderer(FoodTreeitemRenderer foodTreeitemRenderer) {
        this.foodTreeitemRenderer = foodTreeitemRenderer;
    }

}

TreeitemRenderer:

import org.zkoss.zul.DefaultTreeNode;
import org.zkoss.zul.Treecell;
import org.zkoss.zul.Treeitem;
import org.zkoss.zul.TreeitemRenderer;
import org.zkoss.zul.Treerow;

public class FoodTreeitemRenderer implements TreeitemRenderer<DefaultTreeNode<Food>> {

    public FoodTreeitemRenderer() {
    }

    @Override
    public void render(Treeitem treeitem, DefaultTreeNode<Food> food, int index) throws Exception {
        treeitem.setValue(food);
        treeitem.appendChild(new Treerow());
        Treerow treerow = (Treerow) treeitem.getChildren().get(0);

        Object obj = food.getData();

        if (obj instanceof Food) {
            Food fo = (Food) obj;
            treerow.appendChild(new Treecell(fo.getName()));
            treerow.appendChild(new Treecell(fo.getColor()));
            treerow.appendChild(new Treecell(String.valueOf(fo.getQuantity())));
            if (fo.getQuantity() == 3) {
                treeitem.setSelectable(false);
                treeitem.setSelected(false);
            }
        }
    }
}

It'll be thankful if anyone can help to solve it.

Nina

delete flag offensive retag edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2024-02-28 15:49:01 +0800

MDuchemin gravatar image MDuchemin
2560 1 6
ZK Team

It's a little bit counter-intuitive, but the Treeitem is not in control of its own selectable status.

If you use a TreeModel which implements TreeSelectableModel (the DefaultTreeModel does), then the TreeModel gets ownership of the selection state and selection control.

https://www.zkoss.org/wiki/ZKDeveloper'sReference/MVC/Model/TreeModel#SelectionControl

In short, whether a treeitem is selectable or not depends on the value returned by selectionControl.isSelectable(DefaultTreeNode<food>){...}

See a modified viewModel implementing a basic selection control. Relevant part:

        @Override
        public boolean isSelectable(DefaultTreeNode<Food> e) {
            return e.getData().getQuantity()!=3; // if qty is 3, return false (non-selectable)

Here's the full sample:

public class FoodViewModel {

    private DefaultTreeModel<Food> foodTreeModel;
    private FoodTreeitemRenderer foodTreeitemRenderer;
    private Tree tree;

    @Init
    public void init() {
        List<TreeNode<Food>> rootNodes = createFoodData();
        DefaultTreeNode<Food> root = new DefaultTreeNode<>(null, rootNodes);

        foodTreeModel = new DefaultTreeModel<>(root);
        foodTreeitemRenderer = new FoodTreeitemRenderer();
        foodTreeModel.setSelectionControl(new SelectionControl<DefaultTreeNode<Food>>() {
            @Override
            public boolean isSelectable(DefaultTreeNode<Food> e) {
                return e.getData().getQuantity()!=3; // if qty is 3, return false (non-selectable)

            }
            @Override
            public void setSelectAll(boolean selectAll) {
                //do something on select all event
                //used for manual selectAll control
            }
            @Override
            public boolean isSelectAll() {
                //check if all nodes are currently selected, then return result
                //used for manual select all control
                return false;
            }
        });
    }
link publish delete flag offensive edit

Comments

It solved my problem. Thanks a lot!

ynizzz ( 2024-02-28 19:21:22 +0800 )edit
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow
1 follower

RSS

Stats

Asked: 2024-02-27 16:32:54 +0800

Seen: 4 times

Last updated: Feb 28

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More