Не удалось загрузить ошибку скина в Gluon Project

У меня есть пользовательский элемент управления ChoiceTextField с соответствующим ChoiceTextFieldSkin.

protected Skin<?> createDefaultSkin() {
        return new ChoiceFieldSkin<T, ChoiceTextField<T>>(this);
    }

Элемент управления отображается правильно, хотя я получаю следующее Exception:

Failed to load skin 'com.gluonhq.impl.charm.a.b.a.ap' for control ChoiceTextField[id=choiceCounter, styleClass=choice-field colored button flat]
java.lang.IllegalArgumentException: argument type mismatch

Я могу решить ошибку, установив скин в файле CSS:

.choice-field{
    -fx-skin: "com.energymeter.control.skin.ChoiceFieldSkin";
}

Но мне интересно, что вызывает Exception


person jns    schedule 18.05.2016    source источник
comment
Я не могу воспроизвести вашу проблему. Вы каким-то образом расширяете Gluon Charm TextField?   -  person José Pereda    schedule 18.05.2016
comment
Нет, это расширение Control и делегирование Java TextField. (Я мог видеть исключение после того, как включил ведение журнала, которое я отключил LogManager.getLogManager().reset()   -  person jns    schedule 18.05.2016
comment
Почему ваш элемент управления показывает класс стиля button?   -  person José Pereda    schedule 18.05.2016
comment
Я добавил класс стиля кнопки, потому что хотел унаследовать внешний вид. Я не знал, что скин класса стиля также будет загружен. Удаление стиля кнопки исправило ошибку. Благодарю вас!   -  person jns    schedule 19.05.2016


Ответы (1)


Этот короткий фрагмент кода для создания представления с пользовательским элементом управления:

public BasicView(String name) {
    super(name);

    setCenter(new StackPane(new ChoiceTextField()));
}

class ChoiceTextField<T> extends Control {

    public ChoiceTextField() {
        getStyleClass().add("button");
    }

    @Override
    protected Skin<?> createDefaultSkin() {
        return new ChoiceFieldSkin<>(this);
    }
}

class ChoiceFieldSkin<T> extends SkinBase<ChoiceTextField<T>> {

    private final TextField textfield;

    public ChoiceFieldSkin(ChoiceTextField<T> control) {
        super(control);
        textfield = new TextField();

        getChildren().add(textfield);
    }
}

показывает то же исключение:

javafx.scene.control.Control loadSkinClass
Failed to load skin 'com.gluonhq.impl.charm.a.b.a.ap' for control ChoiceTextField@4fb753dd[styleClass=button]
java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at javafx.scene.control.Control.loadSkinClass(Control.java:735)

Если вы посмотрите на javadoc для Control.createDefaultSkin():

Создайте новый экземпляр темы оформления по умолчанию для этого элемента управления. Это вызывается для создания скина для элемента управления , если скин не предоставлен через CSS {@code -fx-skin} или задан явно в подклассе с {@code setSkin(...) }.

(жирный мой).

И когда вы устанавливаете getStyleClass().add("button"), оказывается, что Charm переопределяет ButtonSkin, чтобы обеспечить волновой эффект через CSS, так что у вас есть исключение.

Как вы упомянули, этого исключения не произойдет, если вы явно установите скин через CSS:

public ChoiceTextField() {

    getStyleClass().addAll("choice-field", "button");
        getStylesheets().add(getClass().getResource("style.css").toExternalForm());
} 


.choice-field {
      -fx-skin: '<package name>.ChoiceFieldSkin'
}
person José Pereda    schedule 18.05.2016
comment
Полезно знать, что исключения при загрузке скина только регистрируются, а не перебрасываются. Я бы никогда не заметил свою ошибку, если бы не включил логирование. - person jns; 19.05.2016