I'm designing a custom JavaFX node using FXML. This node fires a custom event. And I would like to know how to add an event handler to the custom event in the FXML of the parent of this node.
I created my handler, passed it to the child as an object property and hooked it into the event system via the setEventHandler
method. But it throws me an error when the event is fired.
Custom event code :
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 component controller :
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's FXML :
<CharacteristicBar fx:id="courageBar" onBarValueChanged="#handleChangeCou"
GridPane.columnIndex="1" GridPane.rowIndex="7"/>
Handler in parent's controller:
@FXML
public void handleChangeCou(ValueUpdatedEvent event){
System.out.println(event.getValue());
}
Still, my event handler isn't called.
Do you guys have any clue on how to hook my handler with the event system ?
Thanks in advance
I could not get the custom event to work but instead I used properties to achieve my goal. Maybe it's intendend this way in JavaFX