Search code examples
javafxfxml

How to solve JavaFX ContextMenu source node?


I have multiple CheckBoxes in the user interface I created in the FXML file.

<CheckBox..>
  <contextMenu>
    <ContextMenu>
      <items>
        <MenuItem text="%uncheckall" onAction="#uncheckAll" />
        <MenuItem text="%checkall" onAction="#checkAll" />
      </items>
    </ContextMenu>
  </contextMenu>
</CheckBox>
...

All CheckBoxes use the same methods, i.e. uncheckAll and checkAll. How can I return ContextMenu's source Node i.e. CheckBox in the handling methods from Event?

@FXML private void uncheckAll(Event event) {
  MenuItem mni = (MenuItem)event.getSource();
  ContextMenu cm = mni.getParentPopup();
  ...???
}

Solution

  • There doesn't appear to be anything in the API for obtaining the owner of a Node's context menu, however the ancestor class of ContextMenu has method setUserData. You can set the CheckBox as the user data of the ContextMenu. Here is an example using code only, i.e. not FXML.

    CheckBox cb = new CheckBox("check");
    MenuItem mi = new MenuItem("menu item");
    mi.setOnAction(this::uncheckAll);
    ContextMenu cm = new ContextMenu(mi);
    cm.setUserData(cb);
    cb.setContextMenu(cm);
    

    Then, in your uncheckAll method, you can retrieve the CheckBox via method getUserData.

    @FXML private void uncheckAll(Event event) {
        MenuItem mi = (MenuItem) event.getSource();
        ContextMenu cm = mi.getParentPopup();
        CheckBox cb = (CheckBox) cm.getUserData();
    }
    

    Edit

    In FXML simply add a userData attribute to the ContextMenu tag.

    <ContextMenu userData="cbxGroup1">