I have a form with a ComboBox
which I'd like to be populated with available values of MyEnum
type:
我有一个带有ComboBox的表单,我希望用MyEnum类型的可用值填充:
public enum MyEnum {
FIRST_CHOICE ("First choice"),
SECOND_CHOICE ("Second choice");
private String value;
MyEnum(String value) {
this.value = value;
}
public String toString() {
return value;
}
}
myComboBox.getItems().setAll(MyEnum.values());
Then, after making a choice and hitting a button for example, I'd like to create a new MyEnum
object. The ideas I came up with are:
然后,在做出选择并按下按钮之后,我想创建一个新的MyEnum对象。我想出的想法是:
Option 1:
Get values from the ComboBox and using switch
statement, create a new MyEnum
regarding to the choice taken.
从ComboBox获取值并使用switch语句,创建一个关于所选内容的新MyEnum。
Option 2:
Make the String values same as the enumerated ones and create MyEnum
using valueOf()
:
使String值与枚举值相同,并使用valueOf()创建MyEnum:
public enum MyEnum {
FIRST_CHOICE ("FIRST_CHOICE"),
SECOND_CHOICE ("FIRST_CHOICE");
...
}
MyEnum myEnum = MyEnum.valueOf(myComboBox.getSelectionModel().getSelectedItem())
---------
So the first option is terrible, I know. Second is a bit better but no so user-friendly (since he will see a text like "FIRST_CHOICE") and I suppose there are better options. I'd like to make it in the best possible way, with separation of View and Model as much as I can but I totally don't know how can I achieve that.
所以第一个选择很糟糕,我知道。第二个好一点,但没有那么用户友好(因为他会看到像“FIRST_CHOICE”这样的文字),我想有更好的选择。我想以最好的方式制作它,尽可能地分离View和Model,但我完全不知道如何实现这一点。
1 个解决方案
#1
2
I'd go with "option 3", and use the a StringConverter
. This will allow you to use enum "under the hood" whilst displaying a more suitable String to the user. This will also allow different strings in different situations, e.g. internationalization, or different comboboxes on top of same underlying type.
我选择“选项3”,然后使用StringConverter。这将允许您在“引擎盖下”使用枚举,同时向用户显示更合适的字符串。这也将允许不同情况下的不同字符串,例如国际化,或基于相同基础类型的不同组合框。
Here I've used a case statement as an example, but could look the value up from properties file etc.
这里我以case语句为例,但可以从属性文件中查看值等。
ComboBox<MyEnum> myComboBox = new ComboBox<>();
myComboBox.getItems().setAll(MyEnum.values());
myComboBox.setConverter(new StringConverter<MyEnum>() {
@Override
public String toString(MyEnum object) {
switch (object) {
case FIRST_CHOICE:
return "foo";
case SECOND_CHOICE:
return "bar";
default:
break;
}
return null;
}
@Override
public MyEnum fromString(String string) {
return null;
}
});
The value returned by the ComboBox will still be of type MyEnum, this can be demonstrated by
ComboBox返回的值仍然是MyEnum类型,这可以通过以下方式演示
myComboBox.valueProperty().addListener((obs, oldValue, newValue) -> {
System.out.println(myComboBox.getValue());
});
Output
SECOND_CHOICE
FIRST_CHOICE
#1
2
I'd go with "option 3", and use the a StringConverter
. This will allow you to use enum "under the hood" whilst displaying a more suitable String to the user. This will also allow different strings in different situations, e.g. internationalization, or different comboboxes on top of same underlying type.
我选择“选项3”,然后使用StringConverter。这将允许您在“引擎盖下”使用枚举,同时向用户显示更合适的字符串。这也将允许不同情况下的不同字符串,例如国际化,或基于相同基础类型的不同组合框。
Here I've used a case statement as an example, but could look the value up from properties file etc.
这里我以case语句为例,但可以从属性文件中查看值等。
ComboBox<MyEnum> myComboBox = new ComboBox<>();
myComboBox.getItems().setAll(MyEnum.values());
myComboBox.setConverter(new StringConverter<MyEnum>() {
@Override
public String toString(MyEnum object) {
switch (object) {
case FIRST_CHOICE:
return "foo";
case SECOND_CHOICE:
return "bar";
default:
break;
}
return null;
}
@Override
public MyEnum fromString(String string) {
return null;
}
});
The value returned by the ComboBox will still be of type MyEnum, this can be demonstrated by
ComboBox返回的值仍然是MyEnum类型,这可以通过以下方式演示
myComboBox.valueProperty().addListener((obs, oldValue, newValue) -> {
System.out.println(myComboBox.getValue());
});
Output
SECOND_CHOICE
FIRST_CHOICE