0

I have a JavaFX Combo Box where, once an item is selected, another combo box is populated with a list of relevant items. So I've set onAction for my Combo Box to be handleSelect() and this is the function that takes care of populating the second combo box.

When should handleSelect() be triggered? When I select an item from the combo box, handleSelect() is triggered as expected. However, handleSelect() is also triggered when I click on the second combo box, even though that second combo box has no onAction set. Additionally, handleSelect() is triggered when I click away to another window.

Is this the expected behavior of an onAction for a JavaFX combo box?

Incidentally, this used to work and now it doesn't and I don't know why. Here's the code...

I have two comboBoxes, one called comboVariable and one called comboOperator. When a variable is selected from comboVariable, the comboOperator box is populated with relational operators that make sense for the variable type selected. To do this I've created a class called UserVariable and an enum type RelationOperator.

@FXML ComboBox<ComboBoxItem<String>> comboVariable;
@FXML ComboBox<SimpleConditional.RelationalOperator> comboOperator;

public void initWindow()
{
    setContents();
}

public void setContents()
{
    System.out.println("setContents called");
    comboVariable.getItems().clear();
    if (getVars().size() > 0) {
        for(Map.Entry<String, UserVariable<? extends Comparable<?>>> varEntry : getVars().entrySet()) {
            comboVariable.getItems().add(new ComboBoxItem<String>(varEntry.getKey(), true));
        }
    }

    // make comboVariable autocomplete
    FxUtil.autoCompleteComboBox(comboVariable, 
            (typedText, itemToCompare) -> itemToCompare.getName().toLowerCase().contains(typedText.toLowerCase()) 
    );
}

@FXML public void handleSelect()
// This method is called whenever a variable name is selected in the comboVariable combobox
{
    System.out.println("handleSelectVar called");

    ComboBoxItem<String> selectedItem = FxUtil.getComboBoxValue(comboVariable);

    if (selectedItem == null) return;

    String varName = selectedItem.getName();

    UserVariable<?> selectedVar = getVar(varName);
    if (selectedVar == null) return;

    myVarType = selectedVar.getType();

    setComboAndLabelBasedOnType();
}

private void setComboAndLabelBasedOnType()
// This helper function is called by handleSelect()
// It sets the available operators to be == and != for Strings and Bool and makes all operators available for
// Doubles and Integers.
{
    System.out.println("setComboAndLabelBasedOnType called");

    comboOperator.getItems().clear();

    switch (myVarType) {
    case STRING:
    case BOOL:
        comboOperator.getItems().addAll(RelationalOperator.EQ, RelationalOperator.NE);
        break;
    case DOUBLE:
    case INT:
        comboOperator.getItems().addAll(RelationalOperator.EQ, RelationalOperator.NE, 
                RelationalOperator.GT, RelationalOperator.GE, RelationalOperator.LT, 
                RelationalOperator.LE);
        break;
    }
}
skrilmps
  • 625
  • 2
  • 10
  • 29
  • 3
    Show us the code of both Comboboxes and how you fill them. – Raw Jun 04 '19 at 06:18
  • Question updated to include code – skrilmps Jun 04 '19 at 14:40
  • 1
    I am not familiar with `FxUtil` but I suspect it may be firing the `ComboBox` at different times as part of the apparent auto-complete functionality. I would recommend adding a listener to the `comboVariable.getSelectionModel().selectedItemProperty()` instead of using `setOnAction()` anyway. – Zephyr Jun 04 '19 at 16:37
  • @Zephyr You were right, it was the autocomplete that was causing problems. I commented that part out and it works as expected. I got the autocomplete combo box implementation from here: https://stackoverflow.com/questions/19924852/autocomplete-combobox-in-javafx Perhaps that solution doesn't work with Java 10 and later (which is roughly when this problem first appeared) – skrilmps Jun 04 '19 at 20:28
  • 2
    That solution calls `setEditable(false)` in a number of places, the ComboBox documentation states that when set to false, the selected value is cleared and the actions are fired, hence the second call. I think Zephyr and I had the same comments on the other post. – kendavidson Jun 05 '19 at 11:46

0 Answers0