mgarin / weblaf

WebLaF is a fully open-source Look & Feel and component library written in pure Java for cross-platform desktop Swing applications.
http://weblookandfeel.com
GNU General Public License v3.0
1.13k stars 234 forks source link

Potential NPE with WebTreeModel when using CheckStateChangeListener #633

Open mgarin opened 4 years ago

mgarin commented 4 years ago

Was mentioned by @Abu-Abdullah on Gitter.

This listener:

searchTree.addCheckStateChangeListener(new CheckStateChangeListener<DefaultMutableTreeNode>()
{
    @Override
    public void checkStateChanged(WebCheckBoxTree<DefaultMutableTreeNode> searchTree, List<CheckStateChange<DefaultMutableTreeNode>> checkStateChanges)
    {
        final java.util.List<DefaultMutableTreeNode> checkedNodes = searchTree.getNodes(CheckState.checked);
        ....

Throws next exception:

java.lang.NullPointerException
    at com.alee.extended.tree.NodesPositionComparator.compare(NodesPositionComparator.java:90)
    at com.alee.extended.tree.NodesPositionComparator.compare(NodesPositionComparator.java:36)
    at java.base/java.util.TimSort.countRunAndMakeAscending(TimSort.java:356)
    at java.base/java.util.TimSort.sort(TimSort.java:220)
    at java.base/java.util.Arrays.sort(Arrays.java:1306)
    at java.base/java.util.ArrayList.sort(ArrayList.java:1720)
    at java.base/java.util.Collections.sort(Collections.java:179)
    at com.alee.extended.tree.DefaultTreeCheckingModel.getNodes(DefaultTreeCheckingModel.java:137)
    at com.alee.extended.tree.WebCheckBoxTree.getNodes(WebCheckBoxTree.java:454)
    at com.alee.extended.tree.WebCheckBoxTree.getNodes(WebCheckBoxTree.java:441)
    at com.myapp.Indexer$2.checkStateChanged(Indexer.java:489)
    at com.alee.extended.tree.DefaultTreeCheckingModel.fireCheckStateChanged(DefaultTreeCheckingModel.java:683)
    at com.alee.extended.tree.DefaultTreeCheckingModel.setChecked(DefaultTreeCheckingModel.java:167)
    at com.alee.extended.tree.WebCheckBoxTree.setChecked(WebCheckBoxTree.java:467)
    at com.myapp.Indexer$22.actionPerformed(Indexer.java:3448)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
    at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
    at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
    at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
    at java.desktop/javax.swing.AbstractButton.doClick(AbstractButton.java:369)
    at java.desktop/javax.swing.AbstractButton.doClick(AbstractButton.java:349)
    at com.myapp.Indexer$8$1.run(Indexer.java:1799)

It only happens with default model (WebTreeModel) used by WebLaF's checkbox tree:

WebCheckBoxTree<DefaultMutableTreeNode> searchTree = new WebCheckBoxTree<>(searchRoot);

It doesn't occur with DefaultTreeModel:

WebCheckBoxTree<DefaultMutableTreeNode> searchTree = new WebCheckBoxTree<>(new DefaultTreeModel(searchRoot));

Initial search for this exception didn't give any results, but I'm pretty sure it might occur in some rare cases or I'm missing something. This will need more testing/debugging.

Abu-Abdullah commented 3 years ago

for some reason, im facing this now even using new DefaultTreeModel(), no clue what is happening here. the exception is little bit changed

javax.swing.tree.MutableTreeNode.getIndex(javax.swing.tree.TreeNode)" because "parent" is null
java.lang.NullPointerException: Cannot invoke "javax.swing.tree.MutableTreeNode.getIndex(javax.swing.tree.TreeNode)" because "parent" is null
at com.alee.extended.tree.NodesPositionComparator.compare(NodesPositionComparator.java:90)
at com.alee.extended.tree.NodesPositionComparator.compare(NodesPositionComparator.java:36)
at java.base/java.util.TimSort.countRunAndMakeAscending(TimSort.java:355)
at java.base/java.util.TimSort.sort(TimSort.java:220)
at java.base/java.util.Arrays.sort(Arrays.java:1306)
at java.base/java.util.ArrayList.sort(ArrayList.java:1721)
at java.base/java.util.Collections.sort(Collections.java:179)
at com.alee.extended.tree.DefaultTreeCheckingModel.getNodes(DefaultTreeCheckingModel.java:137)
at com.alee.extended.tree.WebCheckBoxTree.getNodes(WebCheckBoxTree.java:454)
at com.alee.extended.tree.WebCheckBoxTree.getNodes(WebCheckBoxTree.java:441)
at com.myapp.Indexer$2.checkStateChanged(Indexer.java:422)
at com.alee.extended.tree.DefaultTreeCheckingModel.fireCheckStateChanged(DefaultTreeCheckingModel.java:683)
at com.alee.extended.tree.DefaultTreeCheckingModel.setChecked(DefaultTreeCheckingModel.java:167)
at com.alee.extended.tree.WebCheckBoxTree.setChecked(WebCheckBoxTree.java:467)
at com.myapp.Indexer$22.actionPerformed(Indexer.java:3376)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
at java.desktop/javax.swing.AbstractButton.doClick(AbstractButton.java:369)
at java.desktop/javax.swing.AbstractButton.doClick(AbstractButton.java:349)
at com.myapp.Indexer$8$1.run(Indexer.java:1728)

if this is not enough, i will try to make a sample test case (the code is complex so it will take time to simluate this case)

mgarin commented 3 years ago

So all you do to get this is still simply calling searchTree.getNodes(CheckState.checked);, correct?

mgarin commented 3 years ago

I might actually have a clue about when this happens and why I'm not able to reproduce it. Does your tree show it's root node or is it hidden? and does it have a visible check box as well?

Abu-Abdullah commented 3 years ago

So all you do to get this is still simply calling searchTree.getNodes(CheckState.checked);, correct?

yes, the error appears at this line. the logic is:

Abu-Abdullah commented 3 years ago

I might actually have a clue about when this happens and why I'm not able to reproduce it. Does your tree show it's root node or is it hidden? and does it have a visible check box as well?

root node is displayed all the time and it has a visible check box