在 JavaFX 的 FXML 中,如何为自定义事件声明处理程序?

In JavaFX's FXML, how to declare handlers for custom events?

我正在使用 FXML 设计自定义 JavaFX 节点。此节点触发自定义事件。 我想知道如何在该节点的 parent 的 FXML 中向自定义事件添加事件处理程序。

我创建了我的处理程序,将其作为 object 属性 传递给 child,并通过 setEventHandler 方法将其连接到事件系统中。但是当事件被触发时它会抛出一个错误。

自定义事件代码:

public class ValueUpdatedEvent extends Event {

    public static final EventType<ActionEvent> VALUE =
            new EventType<>(Event.ANY, "VALUE_UPDATED");

    private float value;

    public ValueUpdatedEvent() {
        super(VALUE);
    }

    public float getValue() {
        return value;
    }

    public void setValue(float value) {
        this.value = value;
    }
}


Child 组件控制器:

public class CharacteristicBar extends Component {

    @FXML
    private JFXTextField field;

    @FXML
    private JFXProgressBar bar;

    @FXML
    private JFXButton plus;

    @FXML
    JFXButton minus;

    private ObjectProperty<EventHandler<ValueUpdatedEvent>> onValueUpdated = new ObjectPropertyBase<EventHandler<ValueUpdatedEvent>>() {
        @Override
        public Object getBean() {
            return CharacteristicBar.this;
        }


        @Override protected void invalidated() {
            setEventHandler(new EventType<>(Event.ANY, "onValueUpdated"), get());
        }


        @Override
        public String getName() {
            return "onValueUpdated";
        }
    };

    private SimpleFloatProperty value = new SimpleFloatProperty();

    private boolean readonly = false;

    public CharacteristicBar() {
        super("CharacteristicBar.fxml");
        value.addListener(
                newValue -> {
                    ValueUpdatedEvent event = new ValueUpdatedEvent();
                    event.setValue(value.get());
                    fireEvent(event);
                }
        );

        bar.progressProperty().bind(this.value);
        if (this.readonly) {
            this.field.setEditable(false);
            this.minus.setVisible(false);
            this.plus.setVisible(false);
        }
    }

    @FXML
    private void handleInput(KeyEvent event) {
        try {
            value.set(Float.parseFloat(field.getText()) / 20f);
        } catch (NumberFormatException exception) {
            field.setText("");
        }
    }

    public float getValue() {
        return value.get() * 20f;
    }

    @FXML
    public void handleClickPlus(ActionEvent event) {
        this.value.set((this.value.get() * 20f + 1f) / 20f);
        this.field.setText(String.valueOf(this.value.get() * 20));
    }

    @FXML
    public void handleClickMinus(ActionEvent event) {
        this.value.set((this.value.get() * 20f - 1f) / 20f);
        this.field.setText(String.valueOf(this.value.get() * 20));
    }

    public boolean isReadonly() {
        return readonly;
    }

    public void setReadonly(boolean readonly) {
        this.readonly = readonly;
        this.field.setEditable(!readonly);
        this.minus.setVisible(!readonly);
        this.plus.setVisible(!readonly);
    }

    public EventHandler<ValueUpdatedEvent> getOnValueUpdated() {
        return onValueUpdated.get();
    }

    public ObjectProperty<EventHandler<ValueUpdatedEvent>> onValueUpdatedProperty() {
        return onValueUpdated;
    }

    public void setOnValueUpdated(EventHandler<ValueUpdatedEvent> onValueUpdated) {
        this.onValueUpdated.set(onValueUpdated);
    }
}

Parent 的 FXML:

<CharacteristicBar fx:id="courageBar" onBarValueChanged="#handleChangeCou" 
GridPane.columnIndex="1" GridPane.rowIndex="7"/>

parent 控制器中的处理程序:

    @FXML
    public void handleChangeCou(ValueUpdatedEvent event){
        System.out.println(event.getValue());
    }

仍然没有调用我的事件处理程序。

你们知道如何将我的处理程序与事件系统挂钩吗?

提前致谢

我无法使自定义事件起作用,但我使用属性来实现我的目标。也许它在 JavaFX

中就是这样设计的