JavaFx Combobox值表现异常

时间:2018-08-24 12:18:41

标签: java javafx combobox fxml

我一直在学习javafx,并且正在尝试combobox,但是似乎无法正确地从combobox中获取输出。当我尝试使用combobox中的值作为String时,它给了我ClassCastException:java.lang.Integer无法转换为java.lang.String,当我尝试将值用作int或Integer(都尝试)时给了我相反的ClassCastException:无法将java.lang.String强制转换为java.lang.Integer。

我尝试使用

获取值
<svg width="400" height="110" >

    <rect
            width="300"
            height="100"
            style="fill:rgb(111,111,111)"
    />

</svg>

以及

comboBox.getSelectionModel().getSelectedItem();

我尝试使用valueOf,parseInt和toString显式转换值。使用getClass还会提供ClassCastException:无法将java.lang.String强制转换为java.lang.Integer ..

这是我一直在使用的组合框:

comboBox.getValue();

如何从此组合框中获取价值?我在做什么错了?

2 个答案:

答案 0 :(得分:2)

如果您使用的类型与String不同,并且希望保持ComboBox可编辑,则需要为ComboBox.converter属性分配一个StringConverterString转换为ComboBox的项目类型。否则,当ClassCastException尝试解析组合框ComboBox的输入时,您将得到TextField

注意:向fxml中的元素添加fx:id属性不会导致fx:id和为要使用的元素创建的对象的组合。取而代之的是,它允许您将实例注入控制器中的某个字段,或者稍后在fxml中引用该实例。

由于似乎您想保留2条信息(Stringint),StringInteger都不适合您。您可以创建一个自定义类型:

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>

控制器类

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

        });
    }

}

答案 1 :(得分:0)

您的FXCollections返回String,因为您在集合中声明了String。如果您想要整数,请尝试以下方法:

<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(); 应该返回Integer。