java - 我应该在 JComboBox 中使用枚举还是字符串

标签 java swing

刚刚遇到一个小问题,我很困惑,如果有人不介意快速浏览一下的话。

我的组合框的构造和初始化如下所示,我认为将数据保留为枚举是一个好主意,因为选项都是固定的:

private JComboBox<JobTitle> comboBox = new JComboBox<>();

但是当向 DefaultComboBoxModel 添加元素时,我意识到我不想将选项显示为常量(即我不希望选项以大写形式显示)。

所以我像这样创建了我的枚举(见下文)以便调用 jobTitleModel.addElement(JobTitle.Architect.getName()) 但显然这不会起作用,因为 ComboBox 是枚举类型,而不是字符串类型。

public enum JobTitle {
    ARCHITECT("Architect"), TOWN_PLANNER("Town Planner"), URBAN_DESIGNER("Urban Designer"), LANDSCAPE_GARDENER("Landscape Gardener");

    private final String name;

    private JobTitle(String name){
        this.name = name;
    }

    public String getName(){
         return this.name;
    }
}

所以我不太确定如何解决这个问题?我可以将 ComboBox 和模型更改为 String,但我想我一定在这里遗漏了一些明显的东西。谢谢

最佳答案

为 JComboBox 使用自定义渲染器。例如,下面的代码使用从默认列表单元格渲染器扩展的渲染器。它所做的只是获取 JComboBox 的每个单元格中保存的值(一个 JobTitle 对象),从该对象中提取名称并显示该名称:

JComboBox<JobTitle> jobCombo = new JComboBox<>(JobTitle.values());
jobCombo.setRenderer(new DefaultListCellRenderer() {

    public Component getListCellRendererComponent(JList<?> list,
            Object value,
            int index,
            boolean isSelected,
            boolean cellHasFocus) {
        value = ((JobTitle) value).getName();
        return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
    }

});

为什么要这样做?现在,如果用户从组合框中选择一个项目,它就是一个成熟的 JobTitle 枚举对象,而不是一个字符串。


关于您的评论:

If I wanted to make a method that does the above for a variety of comboBoxes and enums, is a switch the most elegant way to deal with that cast on line 9?

这是一个全新的问题,可能应该单独发布,但一种可能的解决方案是为所有枚举提供相同的接口(interface),例如:

public enum JobTitle implements Textable {
    ARCHITECT("Architect"), TOWN_PLANNER("Town Planner"), URBAN_DESIGNER(
            "Urban Designer"), LANDSCAPE_GARDENER("Landscape Gardener");

    private final String text;

    private JobTitle(String name) {
        this.text = name;
    }

    @Override
    public String getText() {
        return text;
    }
}

public interface Textable {
    String getText();
}

然后创建我自己的渲染器类:

public class TextableRenderer extends DefaultListCellRenderer {
    public Component getListCellRendererComponent(JList<?> list, Object value, int index,
            boolean isSelected, boolean cellHasFocus) {

        value = ((Textable) value).getText();

        return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
    }
}

这适用于任何实现 Textable 接口(interface)的枚举(或类)。

然后使用:

final JComboBox<JobTitle> jobCombo = new JComboBox<>(JobTitle.values());
jobCombo.setRenderer(new TextableRenderer());

关于java - 我应该在 JComboBox 中使用枚举还是字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44911350/

相关文章:

Java:new Something().method() 与临时变量

java - Hibernate 将实例转换为子类

java - Immutables lib 将 @Nullable 添加到 equals() 方法

java - Swing 计时器 GUI 噩梦

java - 如何为Canvas添加JScrollBar?

java - 如何按行使用 cellRenderer

java - tomcat启动时加载问题

java - 加载-操作-更新图片/像素的最佳方法是什么?

java - Jdialog 中的组件未显示

java - 如何防止我的 JScrollPane/JTextArea 超出包含的 JTabbedPane?