首页 文章

无法在Gluon Project上加载皮肤错误

提问于
浏览
1

我有一个自定义控件 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

1 回答

  • 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)
    

    如果您查看 Control.createDefaultSkin() 的javadoc:

    为此控件创建默认外观的新实例 . 如果没有通过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'
    }
    

相关问题