nishihatapalmer / TreeTable

A Java Swing tree table using a standard JTable and any type of TreeNode or TreeModel.
BSD 3-Clause "New" or "Revised" License
6 stars 0 forks source link

clean model and re-populate table #12

Closed fabdoc closed 1 month ago

fabdoc commented 1 month ago

hallo. I try to clean model and put another model on table, but I loose mouse click expand-collapse function.

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index = 3 size = 0
    at utils.BlockModifyArrayList.checkIndex(BlockModifyArrayList.java:312)
    at utils.BlockModifyArrayList.get(BlockModifyArrayList.java:60)
    at extra.treetable.TreeTableModel.toggleExpansion(TreeTableModel.java:2147)

any suggestion to solve?

nishihatapalmer commented 1 month ago

Can you explain what you mean by "clean model" and "put another model on table"?

Clearly something has got out of sync somewhere, but I don't know what you have done to get there.

fabdoc commented 1 month ago

yes! 1) clear model using tableModel.setRowCount(0); 2) generate a new model: rootObject = getModel(); 3) build a new tree: rootNode = TreeUtils.buildTree(rootObject, ParcelleTreeData::getChildren, parent -> parent.getChildren().size() > 0); 4) generate a new treetablemodel: treeTableModel = createTreeTableModel(table, rootNode); 5) reassign renderer: table.getColumnModel().getColumn(0).setCellRenderer(new TreeCellRenderer(treeTableModel);

fabdoc commented 1 month ago

where createTreeTableModel is:

private ParcelleTreeTableModel createTreeTableModel(JTable table1, TreeNode rootNode) {
        ParcelleTreeTableModel localTreeTableModel = new ParcelleTreeTableModel(rootNode, false);
        localTreeTableModel.bindTable(table1, null, new TreeTableHeaderRenderer());
        //mouse click:
        localTreeTableModel.addExpandCollapseListener(new TreeTableModel.ExpandCollapseListener() {
            @Override
            public boolean nodeExpanding(TreeNode node) {
                System.out
                        .println("testtt..nodeExpanding()");
                if (node.getChildCount() == 0) {
                    // if a node is expanding but has no children, set it to allow no children.
                    ((DefaultMutableTreeNode) node).setAllowsChildren(false);
                }
                return true;
            }

            @Override
            public boolean nodeCollapsing(TreeNode node) {
                System.out.println("testtt.nodeCollapsing()");
                return true;
            }
        });
        return localTreeTableModel;
    }

note that if i call this sequence when all is 'new' (first assignement) it works fine. but if I call twice, changing nodes structure or node number, it don't works

nishihatapalmer commented 1 month ago

Thanks, I will have a look over the weekend.

nishihatapalmer commented 1 month ago

Some questions:

1. clear model using tableModel.setRowCount(0); You should not be using a table model at all. The TreeTableModel IS the table model, but TableModel interface does not define SetRowCount(). What is this?

5. reassign renderer I don't understand why you need to do this; binding a table to the TreeTableModel should assign the tree renderer automatically to the first column (index 0).

Other than that, your createTreeTableModel() method looks OK to me.

nishihatapalmer commented 1 month ago

In general, you bind the TreeTableModel to a Jtable, and set the root node.

If you want to see a different tree, you can just set a new root, you don't need to set row counts or bind a new TreeTableModel (although that should work too).

fabdoc commented 1 month ago

thanks! now it works. please note that

1. clear model using tableModel.setRowCount(0); You should not be using a table model at all. The TreeTableModel IS the table model, but TableModel interface does not define SetRowCount(). What is this?

I was using table.getTableModel.setRowCount(0); now replaced by `` rootNode = TreeUtils.buildTree(new ParcelleTreeData(), ParcelleTreeData::getChildren, parent -> parent.getChildren().size() > 0);

treeTableModel.setRoot(rootNode); ``

5. reassign renderer I don't understand why you need to do this; binding a table to the TreeTableModel should assign the tree renderer automatically to the first column (index 0).

now removed: I was calling before because using my "clear" method, new model loose renderer, because was a wrong clean.

nishihatapalmer commented 1 month ago

Glad to hear it! Maybe I need to add some more documentation to make this clearer.