我有一个自定义控件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
这段创建带有自定义控件的视图的代码片段:
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'
}