在 FXML 中传递枚举

Chr*_*ith 2 java javafx fxml

我正在制作一个自定义 FXML 组件。我想要做的是将枚举传递给组件,以便它可以从枚举中检索所有值。这是自定义组件的片段:

public ChoiceBoxSetting(@NamedArg("values") Enum values) {
    choiceBox.getItems().setAll(values.getDeclaringClass().getEnumConstants());
Run Code Online (Sandbox Code Playgroud)

这是创建它的 FXML:

<ChoiceBoxSetting>
    <values>
        <MyCustomValues/>
    </values>
</ChoiceBoxSetting>
Run Code Online (Sandbox Code Playgroud)

这是MyCustomValues枚举:

public enum MyCustomValues {
    HI, HELLO, ME
}
Run Code Online (Sandbox Code Playgroud)

所以当我运行它时,我得到这个异常:

Caused by: javafx.fxml.LoadException: MyCustomValues is not a valid type.
Run Code Online (Sandbox Code Playgroud)

我试图传递枚举本身,而不是枚举值之一,例如MyCustomValues.HI.

Jam*_*s_D 5

名称与类名相对应的元素是实例FXMLLoader化该类的指令;所以

<MyCustomValues/>
Run Code Online (Sandbox Code Playgroud)

将导致FXMLLoader尝试调用new MyCustomValues(),这当然不能用枚举类型来执行。

理想情况下,您希望在Class此处传递实际对象本身,但由于我看不到Class<?>在 FXML 中实例化 a 的方法,我认为您能做的最好的事情就是传递类的名称。例如:

package application;

import javafx.beans.NamedArg;
import javafx.scene.control.ChoiceBox;

public class EnumChoiceBox<E extends Enum<E>> extends ChoiceBox<E> {
    
    public EnumChoiceBox(@NamedArg("enumType") String enumType) throws Exception {
        Class<E> enumClass = (Class<E>) Class.forName(enumType);
        getItems().setAll(enumClass.getEnumConstants());
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.StackPane?>
<?import application.EnumChoiceBox?>

<StackPane xmlns:fx="http://javafx.com/fxml/1">
    <EnumChoiceBox enumType="application.MyCustomValues"/>
</StackPane>
Run Code Online (Sandbox Code Playgroud)

(替换application为实际的包名称MyCustomValues)。


更新

与我八年前的看法相反,通过问题中的初始设置,这实际上是可能的。需要传递的只是枚举中的一个值(而不是枚举类本身),这可以使用以下方法完成fx:constant

<ChoiceBoxSetting>
    <values>
        <MyCustomValues fx:constant="HI"/>
    </values>
</ChoiceBoxSetting>
Run Code Online (Sandbox Code Playgroud)

传递哪个值的选择是任意的。