0

I wrote the following custom ChoiceBox that populates itself from a generic Enum implementing my interface DisplayName below:

import java.util.Objects;

import javafx.scene.control.ChoiceBox;
import javafx.util.StringConverter;

public class EnumChoiceBox<T extends Enum<T>&DisplayName<T>> extends ChoiceBox<T> {

    public EnumChoiceBox(Class<T> enumType) {
        super();
        getItems().setAll(enumType.getEnumConstants());
        this.setConverter(new StringConverter<T>() {
            @Override
            public String toString(T object) {
                return object.toDisplayName();
            }
            @Override
            public T fromString(String string) {
                for(T t : getItems()) if(t.toDisplayName().equals(string)) return t;
                return null;
            }
        });
    }

    @SuppressWarnings("unchecked")
    public EnumChoiceBox(T defaultValue) {
        this((Class<T>) Objects.requireNonNull(defaultValue, "defaultValue must not be null!").getClass());
        setValue(defaultValue);
    }

    public EnumChoiceBox(Class<T> enumType, T defaultValue) {
        this(enumType);
        setValue(defaultValue);
    }
}

public interface DisplayName<T extends Enum<T>> {
    public default String toDisplayName() {
        return this.toString().replace('_', ' ').toLowerCase();
    }
}

Basically, everything works and the complier is also satisfied with the first and the third constructor. However, it seems to me that the two arguments in the third constructors are unnecessary: it should be enough to pass the default value as this already contains the class information.

So, this is what I tried to achieve with the second constructor, but there I get a warning that I made an unchecked cast. Is there any way to solve / get around that problem (other than just suppressing the warning)?

floxbr
  • 144
  • 1
  • 9
  • 1
    I don't think there is. `getClass`'s return type is `Class>` so it's either using a cast or using the raw type which both yield warnings. I'd recommend chaining the constructor call to the third constructor though, assuming you'll keep that one since you otherwise duplicate the code for setting the default value (even if it's currently just a single method call). – fabian Mar 11 '19 at 15:28
  • Thanks, ultimately I'll remove the third one because the other two should be enough. (As shown here, there is also no need for DisplayName to be generic, just if anyone was wondering about that.) – floxbr Mar 11 '19 at 15:46

0 Answers0