JavaFx Combobox значение действует странно - PullRequest
0 голосов
/ 24 августа 2018

Я изучал javafx и пробовал комбинированный список, но, похоже, не могу правильно выводить его из списка. Когда я пытаюсь использовать значение из выпадающего списка в качестве String, оно дает мне ClassCastException: java.lang.Integer не может быть приведено к java.lang.String, и когда я пытаюсь использовать значение как int или Integer (пробовал оба), его дает мне противоположное ClassCastException: java.lang.String не может быть приведен к java.lang.Integer.

Я пытался получить значение, используя

comboBox.getSelectionModel().getSelectedItem();

, а также с

comboBox.getValue();

Я попытался преобразовать значения явно с помощью valueOf, parseInt и toString. Использование getClass также дает ClassCastException: java.lang.String не может быть приведен к 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>

Как мне получить значение из этого списка? Что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 24 августа 2018

Если вы используете какой-либо тип, отличный от String, и хотите сохранить ComboBox доступным для редактирования, вам нужно присвоить StringConverter свойству ComboBox.converter, которое можно преобразовать String для типа элемента ComboBox. В противном случае вы получите ClassCastException, когда ComboBox попытается проанализировать ввод комбинированного списка TextField.

Примечание. Добавление атрибута 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>

Контроллер класса

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

        });
    }

}
0 голосов
/ 24 августа 2018

Ваши 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>

And comboBox.getValue ();Должен вернуть Integer.

...