bolidor
bolidor

Reputation: 39

TreeCellRenderer: applying different style of the node's text which is depending on the user object's type

I have a tree with DefaultMutableTreeNodes only. I want to write a TreeCellRenderer that depends on the type of the contained user object. I tried to write a simple example (which doesn't work. That's why I ended up here). On the first level beyond the root node, the types of the user objects are either AANodeUserObjector LocalAANodeUserObject. Both should be rendered with directory icons even though there might be no child. The other feature of this renderer is, that it should render nodes with user object type AANodeUserObject in red color and bold when they are not "current" (in my example, this is always true). Here is my code:

    public Component getTreeCellRendererComponent(final JTree tree, final Object value, final boolean sel, final boolean expanded, final boolean leaf, final int row, final boolean hasFocus)
    {
        super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
        // Precondition für Default TreeNode
        Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
        if (userObject instanceof TestTree.AANodeUserObject || userObject instanceof TestTree.LocalAANodeUserObject)
        {
            if (expanded)
            {
                setIcon(openIcon);
            }
            else
            {
                setIcon(closedIcon);
            }
        }

        if (userObject instanceof TestTree.AANodeUserObject)
        {
            TestTree.AANodeUserObject aAnode = (TestTree.AANodeUserObject) userObject;
            if (!mVersionInfo.get(aAnode))
            {
                renderOutdatedAaNode();
            } else {
                renderDefault();
            }
        }  else {
            renderDefault();
        }
        return this;
    }

    private void renderDefault()
    {
        setTextNonSelectionColor(cColorBlack);
        setTextSelectionColor(cColorBlack);
        setFont(getFont().deriveFont(Font.PLAIN));
    }

    private void renderOutdatedAaNode()
    {
        setTextNonSelectionColor(cColorRed);
        setTextSelectionColor(cColorRed);
        setFont(getFont().deriveFont(Font.BOLD));
    }

You can see the result on the attached pictureThe resulting tree.

What irritates me is that the directory-icon-thing works fine, the text style doesn't: only the second node (Hashmap value is false) AANodeUserObject should be red and nothing else. What am I doing wrong? Can somebody help? Thanks! Mathias

Upvotes: 0

Views: 3517

Answers (3)

Samonosuke
Samonosuke

Reputation: 1

Why you are returning "this"?

You should create a variable in which you temporarily store the returned value of the method from the super class which you are calling at the beginning. And then you have to modify this reference and return it at the end. Then you would not have any problems!

Upvotes: 0

bolidor
bolidor

Reputation: 39

I solved the problems by calling super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus) twice:

  • The first time as first line of getTreeCellRendererComponent(). Without the call, getFont(setFont()) to set the font style to bold will return a NullPointerException.

  • The second time at the last line in the method to render the nodes properly.

There might be another solution but after many different tries, this has worked for me.

Upvotes: 0

svaor
svaor

Reputation: 2245

Boolean isCurrent = false;
if (!isCurrent)

What do you want to do by this code?

Also you need to implement "else" for this "if":

if (userObject instanceof TestTree.AANodeUserObject)
{
    //...
}

Otherwise all your renderer components will be printed with red font.

Upvotes: 1

Related Questions