2

I populate my JTree with nodes from enum values. But the nodes display in all uppercase text. This is undesirable as I would like the nodes to display in lower case.

example:

public enum DaysOfTheWeek {     


    MONDAY("Monday", "MON", "First day of the work week."), 
    //etc ...  

    private final String fullName;  
    private final String abbrvName;  
    private final String description;  

    DaysOfTheWeek(String fullName, String abbrvName, String description) {  
        this.fullName = fullName; 
        //etc ...  
    }  

    public String getFullName() {  
        return fullName;  
    }  
}

I have tried:

List<DefaultMutableTreeNode> daysOfWeekNodes = new ArrayList<>();  

for(DaysOfTheWeek dotw : DaysOfTheWeek.values()) {  

        daysOfWeekNodes.add(new DefaultMutableTreeNode(dotw.getFullName()));  
        daysOfWeekNodes.get(dotw.ordinal()).setUserObject(dotw);  
}

The node displays as: MONDAY But I want it to display as: Monday

text based graphic example:

Days  
    |  
    ---Monday  
    |  
    ---Tuesday

not

Days  
    |  
    ---MONDAY  
    |  
    ---TUESDAY  

How do I get my tree node associated with the enum value, but its text on the tree to use the full name String? Or in other words, how to set a tree node user object but have its name different?

*note - an easy fix is to go against convention and name my values how I want them displayed in the tree, not all uppercase.

CompSci-PVT
  • 1,303
  • 2
  • 10
  • 23
  • This code looks good. The problem is probably at the point of display, not at the point of tree creation. Can you post the display code? – durron597 May 03 '13 at 12:40
  • Don't really have any display code. I just add the tree to my panel after it is created. – CompSci-PVT May 03 '13 at 13:15

2 Answers2

3

You need to use a TreeCellRenderer.

Here is one way to implement this:

import java.awt.Component;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;

public class TestTree {

    public enum DaysOfTheWeek {

        MONDAY("Monday", "MON", "First day of the work week."), TUESDAY("Tuesday", "TUE", "Second day of the work week");
        // etc ...

        private final String fullName;
        private final String abbrvName;
        private final String description;

        private DaysOfTheWeek(String fullName, String abbrvName, String description) {
            this.fullName = fullName;
            this.abbrvName = abbrvName;
            this.description = description;
        }

        public String getFullName() {
            return fullName;
        }

        public String getAbbrvName() {
            return abbrvName;
        }

        public String getDescription() {
            return description;
        }
    }

    public class MyTreeCellRenderer extends DefaultTreeCellRenderer {

        @Override
        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row,
                boolean hasFocus) {
            Component cell = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
            if (value instanceof DefaultMutableTreeNode && ((DefaultMutableTreeNode) value).getUserObject() instanceof DaysOfTheWeek) {
                ((JLabel) cell).setText(((DaysOfTheWeek) ((DefaultMutableTreeNode) value).getUserObject()).getFullName());
            }
            return cell;
        }
    }

    private JFrame f;
    private JTree tree;

    protected void initUI() {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Days");
        for (DaysOfTheWeek dotw : DaysOfTheWeek.values()) {
            root.add(new DefaultMutableTreeNode(dotw));
        }
        final DefaultTreeModel model = new DefaultTreeModel(root);
        tree = new JTree(model);
        tree.setRootVisible(true);
        tree.setShowsRootHandles(true);
        ToolTipManager.sharedInstance().registerComponent(tree);
        tree.setCellRenderer(new MyTreeCellRenderer());
        f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLocationRelativeTo(null);
        f.add(new JScrollPane(tree));
        f.pack();
        f.setVisible(true);
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestTree().initUI();
            }
        });
    }

}

Take a look at the JTree tutorial.

Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • Wow, I was not expecting to have to craft a custom tree cell renderer in order to change the tree node text. – CompSci-PVT May 03 '13 at 13:14
  • @JavaPVT you could also directly set the FullName of the days of the week as the user object of the DefaultMutableTreeNode but then you only manipulate `String` which is not really recommended. – Guillaume Polet May 03 '13 at 13:18
  • I guess the really easy way would be to go against convention and just name my enum values not in uppercase. – CompSci-PVT May 03 '13 at 13:21
  • @JavaPVT Not recommended: your UI should not depend on the way you coded. Actually, there is a simpler way but it is not recommended either. You could override the `toString()` method of your `enum` and return the "fullName". But `toString()` is only meant for developers, not for display. – Guillaume Polet May 03 '13 at 13:23
  • VERY interesting ... but not sure if I should do it :) – CompSci-PVT May 03 '13 at 13:26
  • 1
    @JavaPVT The clean and correct way to do what you want is to use a `TreeCellRenderer`, no doubt about that. I would really not recommend to change the name you gave to your enum constants. I would not recommend to override `toString()` either. People always start by saying, it was just to do a very small thing, quick & dirty, but eventually this gets into something bigger and bigger and you see odd bugs appear. – Guillaume Polet May 03 '13 at 13:29
0

Make a change here:

  List<DefaultMutableTreeNode> daysOfWeekNodes = new ArrayList<DefaultMutableTreeNode>();

Then try this:

  titleLabel.setText(node.getFullName());
hamid
  • 2,033
  • 4
  • 22
  • 42
  • Unfortunately, it doesn't seem the node will type cast to my enum object. – CompSci-PVT May 03 '13 at 12:51
  • Actually, just realized, the label is not the problem. I want to the node text to display "Monday" not "MONDAY" which is how the enum value is typed in the class. – CompSci-PVT May 03 '13 at 12:59