如何正确使用具有多个值的枚举

时间:2018-12-10 23:06:14

标签: java swing

Java的新手,试图弄清楚如何在这种情况下正确使用枚举;

用户从“组合框”下拉列表中选择其模型,例如

comboBox1.setModel(new DefaultComboBoxModel<>(new String[] {
  ...
  Focus,
  Mondeo,
  Fiesta,
  ...
}));

然后,我需要找到一种方法来获取用户在我的枚举中选择的字符串的carId:

public enum Ford{
 ...
 FOCUS("Focus", 26),
 MONDEO("Mondeo", 6),
 FIESTA("Fiesta", 13),
 ...
 ;

 private final String name;
 private final int carId;
}

我当时正在考虑使用某种比较器循环,该循环试图将收集到的字符串与Ford.name进行匹配,如果匹配,则返回carId:

    public String getCarId() {
    String selectedItem = comboBox1.getSelectedItem().toString();
    for (Ford c : Ford.values()) {
        if (c.name().equals(selectedItem)) {
            return c.carId
        }
    }
    return false;
    }

但是我不确定如何继续/解决我的问题。

我的逻辑是否全部消失或我完全处于正确的轨道上?

3 个答案:

答案 0 :(得分:4)

跟踪枚举对象,而不是其标签

保留对用户选择的enum object的引用,而不是对枚举对象的显示名称的字符串的引用。

// Display combobox
// User picks an item.
// Your event-handling code reacts by remembering which *object* not *string* was select.
Ford fordSelectedByUser = … ;  // You pull reference from the data model backing your widget. 

我不知道您使用的是哪个组合框窗口小部件。例如,在Vaadin框架中,combobox由对象的数据模型支持。也许您正在使用Swing?我不再记得Swing的工作原理的详细信息,而是瞥了一眼this documentation,看来您可以使用对象支持组合框并使用自定义渲染器。

JComboBox< Ford >,而不是JComboBox< String >

制作一个JComboBox来容纳Ford个对象,而不是String个对象。您可以通过调用values()获得所有枚举值的数组。该方法是一种奇怪的方法,尽管在Enum方法文档中有所提及,但并未在Enum.valueOf的JavaDoc上列出–这是一种“隐式”方法,但我认为我们并不关心繁琐的技术细节在那里。

Ford[] fords = Ford.values() ; // Get array of all the objects defined by this enum.
JComboBox< Ford > fordsComboBox = new JComboBox( fords );

跟踪所选的Ford对象,而不是其显示名称。

public void actionPerformed( ActionEvent e ) {
    JComboBox cb = ( JComboBox )e.getSource() ;
    Ford selectedFord = ( Ford )cb.getSelectedItem() ;  // Is casting still needed, or is Swing Generics-aware? Maybe: Ford selectedFord = ( JComboBox< Ford > )e.getSource().getSelectedItem() ;
    updateLabel( selectedFord.getDisplayName() ) ;
}

您的自定义渲染器将调用您将编写的枚举Ford对象的getDisplayName方法。

package com.basilbourque.example;

public enum Ford {

    FOCUS( "Ford" , 26 ),
    MONDEO( "Mondeo" , 6 ),
    FIESTA( "Fiesta" , 13 );

    private final String displayName;
    private final int id;

    // Constructor
    Ford ( String name , int carId ) {
        this.displayName = name;
        this.id = carId;
    }

    // Getters
    public String getDisplayName ( ) {
        return this.displayName;
    }

    public int getId ( ) {
        return this.id;
    }

    // `Object` methods
    @Override
    public String toString ( ) {
        return "Ford{ " +
                "id=" + id +
                ", displayName='" + displayName + '\'' +
                " }";
    }

}

提示:

  • 在整个代码库中,使用Ford对象,而不仅仅是其ID号的整数或仅是其显示名称的字符串。这使您的代码更具自记录性,提供了type-safety,并确保了有效的值。
  • 要收集Enum个对象的子集,请使用EnumSetEnumMap类。这些是SetMap接口的高性能低内存实现。
  • 只有在编译时已知域(所有可能值的集合)的情况下,记住Enum是合适的。添加或淘汰任何汽车都意味着编辑您的Ford枚举类并重新编译。
    • 相比之下,如果您的应用可以在运行时添加更多Ford辆汽车,或者淘汰任何一辆,那么您将无法使用Enum。您将使Ford成为常规类而不是Enum的子类,并在我们执行任何POJOcollect them时实例化它们。

答案 1 :(得分:1)

You don't need to iterate on all the values because you can easily get the enum value in O(1) with Enum.valueOf(String name)

在您的情况下,Ford.valueOf(comboBox1.getSelectedItem().toString()).getCarId() 应该可以。

答案 2 :(得分:0)

您已经正确使用了它,只是做了一些小改动

public enum Ford {
     FOCUS("Ford", 26),
     MONDEO("Mondeo", 6),
     FIESTA("Fiesta", 13);

     private final String name; //Good
     private final int carId; //Good


    /** This is a constructor for the enum variable */
    Ford(String name, int carId) {
        this.name = name; //stores the name variable for the enum
        this.carId = carId;
    }


    public int getCarId() { 
        return this.carId; //gets the carID from the enum variable
    }

    public String getCarName() { 
        return this.name; //gets the car name from the enum variable
    }
}

要使用此枚举类,这里的值是一个示例

    public static void main(String[] args) {

        /** This is how you reference an enum value directly */
        System.out.println("Type: " + Ford.FOCUS 
                    + ", Name: " + Ford.FOCUS.getCarName() 
                    + ", ID: " + Ford.FOCUS.getCarId());


        /** This is how you can cycle through all of the values in this enum class */

        for (final Ford f : Ford.values())
            System.out.println("Type: " + f 
                    + ", Name: " + f.getCarName() 
                    + ", ID: " + f.getCarId());

    } 

另外,请注意,在Java中,关键字“ this”用于引用全局变量,该全局变量是使用“ this”的类/枚举的成员。这表示“ this class的成员”