【问题标题】:Java tree nodes from enum values来自枚举值的 Java 树节点
【发布时间】:2013-04-27 20:56:35
【问题描述】:

我用枚举值中的节点填充我的 JTree。但节点以全部大写文本显示。这是不可取的,因为我希望节点以小写形式显示。

示例:

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;  
    }  
}

我试过了:

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

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

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

节点显示为:MONDAY 但我希望它显示为:星期一

基于文本的图形示例:

Days  
    |  
    ---Monday  
    |  
    ---Tuesday

不是

Days  
    |  
    ---MONDAY  
    |  
    ---TUESDAY  

如何让我的树节点与枚举值关联,但它在树上的文本使用全名字符串?或者换句话说,如何设置树节点用户对象但名称不同?

*注意 - 一个简单的解决方法是违反约定并命名我希望它们在树中显示的值,而不是全部大写。

【问题讨论】:

  • 这段代码看起来不错。问题可能在于显示点,而不是树创建点。可以贴一下显示代码吗?
  • 实际上没有任何显示代码。我只是在创建树后将它添加到我的面板中。

标签: java swing enums jtree treecellrenderer


【解决方案1】:

您需要使用TreeCellRenderer

这是一种实现方式:

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();
            }
        });
    }

}

看看JTree tutorial

【讨论】:

  • 哇,我没想到必须制作自定义树单元格渲染器才能更改树节点文本。
  • @JavaPVT 您也可以直接将星期几的 FullName 设置为 DefaultMutableTreeNode 的用户对象,但您只能操作 String,这并不推荐。
  • 我想最简单的方法是违反约定,只命名我的枚举值而不是大写。
  • @JavaPVT 不推荐:您的 UI 不应依赖于您的编码方式。实际上,有一种更简单的方法,但也不推荐。您可以覆盖 enumtoString() 方法并返回“fullName”。但toString() 仅适用于开发人员,不用于展示。
  • @JavaPVT 使用TreeCellRenderer,这是毫无疑问的。我真的不建议更改您为枚举常量提供的名称。我也不建议覆盖toString()。人们总是说,这只是做一件很小的事情,又快又脏,但最终这会变成越来越大的事情,你会看到奇怪的错误出现。
【解决方案2】:

在此处进行更改:

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

然后试试这个:

  titleLabel.setText(node.getFullName());

【讨论】:

  • 不幸的是,该节点似乎不会将类型转换为我的枚举对象。
  • 其实刚刚意识到,标签不是问题。我希望节点文本显示“星期一”而不是“星期一”,这是在类中键入枚举值的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-11
  • 2011-10-27
  • 1970-01-01
  • 2016-01-18
  • 2010-12-10
  • 2023-03-05
相关资源
最近更新 更多