JavaFx Combobox 值行为怪异
JavaFx Combobox value acting wierd
我一直在学习 javafx,我正在尝试组合框,但似乎无法正确地从组合框中获取输出。当我尝试将组合框的值用作字符串时,它给我 ClassCastException: java.lang.Integer cannot be cast to java.lang.String,当我尝试将该值用作 int 或 Integer(都尝试过)时给我相反的 ClassCastException: java.lang.String cannot be cast to java.lang.Integer.
我尝试使用
获取值
comboBox.getSelectionModel().getSelectedItem();
还有
comboBox.getValue();
我已经尝试使用 valueOf、parseInt 和 toString 显式转换值。使用 getClass 还会产生 ClassCastException:java.lang.String cannot be cast to java.lang.Integer..
这是我一直在使用的组合框:
<ComboBox fx:id="comboBox" editable="true" promptText="Enter Period in Days" >
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:id="week" fx:value="7" />
<String fx:id="fortnite" fx:value="14" />
<String fx:id="month" fx:value="30" />
<String fx:id="monthx3" fx:value="90" />
<String fx:id="year_2" fx:value="180" />
<String fx:id="year" fx:value="365"/>
</FXCollections>
</items>
</ComboBox>
如何从此组合框中获取值?我做错了什么?
您的 FXCollections return 字符串,因为您在集合中声明了字符串。如果你想要整数试试这个:
<ComboBox fx:id="comboBox" editable="true" promptText="Enter Period in Days" >
<items>
<FXCollections fx:factory="observableArrayList">
<Integer fx:id="week" fx:value="7" />
<Integer fx:id="fortnite" fx:value="14" />
<Integer fx:id="month" fx:value="30" />
<Integer fx:id="monthx3" fx:value="90" />
<Integer fx:id="year_2" fx:value="180" />
<Integer fx:id="year" fx:value="365"/>
</FXCollections>
</items>
</ComboBox>
并且
comboBox.getValue();
应该return整数。
如果您使用与 String
不同的类型并希望保持 ComboBox
可编辑,您需要将 StringConverter
分配给 ComboBox.converter
属性 能够将 String
转换为 ComboBox
的项目类型。否则,当 ComboBox
尝试解析组合框 TextField
.
的输入时,您将得到 ClassCastException
注意:将 fx:id
属性添加到 fxml 中的元素不会导致 fx:id
和为要使用的元素创建的对象的组合。相反,它所做的只是允许您将实例注入控制器中的字段或稍后在 fxml 中引用实例。
因为您似乎想要保留 2 条信息(String
和 int
),所以 String
和 Integer
都不适合您。您可以创建自定义类型:
public class NamedDuration {
private final int days;
private final String name;
public NamedDuration(@NamedArg("days") int days, @NamedArg("name") String name) {
this.days = days;
this.name = name;
}
public int getDays() {
return days;
}
public String getName() {
return name;
}
@Override
public String toString() {
return name;
}
}
<ComboBox fx:id="comboBox" editable="true" onAction="#comboChange" promptText="Enter Period in Days">
<items>
<FXCollections fx:factory="observableArrayList">
<NamedDuration name="week" days="7"/>
<NamedDuration name="fortnite" days="14"/>
<NamedDuration name="month" days="30"/>
<NamedDuration name="monthx3" days="90"/>
<NamedDuration name="year_2" days="180"/>
<NamedDuration name="year" days="365"/>
</FXCollections>
</items>
</ComboBox>
控制器class
public class FXML2Controller {
@FXML
private ComboBox<NamedDuration> comboBox;
@FXML
private void comboChange() {
NamedDuration duration = comboBox.getValue();
if (duration != null) {
System.out.format("%d days = %s\n", duration.getDays(), duration.getName());
}
}
@FXML
private void initialize() {
// set converter to convert between String and NamedDuration
comboBox.setConverter(new StringConverter<NamedDuration>() {
@Override
public String toString(NamedDuration object) {
return object == null ? "" : object.getName();
}
@Override
public NamedDuration fromString(String string) {
if (string == null || string.isEmpty()) {
return null;
}
// try matching names
for (NamedDuration nd : comboBox.getItems()) {
if (nd.getName().equalsIgnoreCase(string)) {
return nd;
}
}
// try matching number
int days;
try {
days = Integer.parseInt(string);
} catch (NumberFormatException ex) {
return null;
}
for (NamedDuration nd : comboBox.getItems()) {
if (days == nd.getDays()) {
return nd;
}
}
return null;
}
});
}
}
我一直在学习 javafx,我正在尝试组合框,但似乎无法正确地从组合框中获取输出。当我尝试将组合框的值用作字符串时,它给我 ClassCastException: java.lang.Integer cannot be cast to java.lang.String,当我尝试将该值用作 int 或 Integer(都尝试过)时给我相反的 ClassCastException: java.lang.String cannot be cast to java.lang.Integer.
我尝试使用
获取值comboBox.getSelectionModel().getSelectedItem();
还有
comboBox.getValue();
我已经尝试使用 valueOf、parseInt 和 toString 显式转换值。使用 getClass 还会产生 ClassCastException:java.lang.String cannot be cast to java.lang.Integer..
这是我一直在使用的组合框:
<ComboBox fx:id="comboBox" editable="true" promptText="Enter Period in Days" >
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:id="week" fx:value="7" />
<String fx:id="fortnite" fx:value="14" />
<String fx:id="month" fx:value="30" />
<String fx:id="monthx3" fx:value="90" />
<String fx:id="year_2" fx:value="180" />
<String fx:id="year" fx:value="365"/>
</FXCollections>
</items>
</ComboBox>
如何从此组合框中获取值?我做错了什么?
您的 FXCollections return 字符串,因为您在集合中声明了字符串。如果你想要整数试试这个:
<ComboBox fx:id="comboBox" editable="true" promptText="Enter Period in Days" >
<items>
<FXCollections fx:factory="observableArrayList">
<Integer fx:id="week" fx:value="7" />
<Integer fx:id="fortnite" fx:value="14" />
<Integer fx:id="month" fx:value="30" />
<Integer fx:id="monthx3" fx:value="90" />
<Integer fx:id="year_2" fx:value="180" />
<Integer fx:id="year" fx:value="365"/>
</FXCollections>
</items>
</ComboBox>
并且 comboBox.getValue(); 应该return整数。
如果您使用与 String
不同的类型并希望保持 ComboBox
可编辑,您需要将 StringConverter
分配给 ComboBox.converter
属性 能够将 String
转换为 ComboBox
的项目类型。否则,当 ComboBox
尝试解析组合框 TextField
.
ClassCastException
注意:将 fx:id
属性添加到 fxml 中的元素不会导致 fx:id
和为要使用的元素创建的对象的组合。相反,它所做的只是允许您将实例注入控制器中的字段或稍后在 fxml 中引用实例。
因为您似乎想要保留 2 条信息(String
和 int
),所以 String
和 Integer
都不适合您。您可以创建自定义类型:
public class NamedDuration {
private final int days;
private final String name;
public NamedDuration(@NamedArg("days") int days, @NamedArg("name") String name) {
this.days = days;
this.name = name;
}
public int getDays() {
return days;
}
public String getName() {
return name;
}
@Override
public String toString() {
return name;
}
}
<ComboBox fx:id="comboBox" editable="true" onAction="#comboChange" promptText="Enter Period in Days">
<items>
<FXCollections fx:factory="observableArrayList">
<NamedDuration name="week" days="7"/>
<NamedDuration name="fortnite" days="14"/>
<NamedDuration name="month" days="30"/>
<NamedDuration name="monthx3" days="90"/>
<NamedDuration name="year_2" days="180"/>
<NamedDuration name="year" days="365"/>
</FXCollections>
</items>
</ComboBox>
控制器class
public class FXML2Controller {
@FXML
private ComboBox<NamedDuration> comboBox;
@FXML
private void comboChange() {
NamedDuration duration = comboBox.getValue();
if (duration != null) {
System.out.format("%d days = %s\n", duration.getDays(), duration.getName());
}
}
@FXML
private void initialize() {
// set converter to convert between String and NamedDuration
comboBox.setConverter(new StringConverter<NamedDuration>() {
@Override
public String toString(NamedDuration object) {
return object == null ? "" : object.getName();
}
@Override
public NamedDuration fromString(String string) {
if (string == null || string.isEmpty()) {
return null;
}
// try matching names
for (NamedDuration nd : comboBox.getItems()) {
if (nd.getName().equalsIgnoreCase(string)) {
return nd;
}
}
// try matching number
int days;
try {
days = Integer.parseInt(string);
} catch (NumberFormatException ex) {
return null;
}
for (NamedDuration nd : comboBox.getItems()) {
if (days == nd.getDays()) {
return nd;
}
}
return null;
}
});
}
}