Valijon Valijon - 12 days ago 7
Java Question

JavaFx ComboBox valueProperty().addListener(new ChangeListener<String>() progressively repeated

I am using ComboBox on JavaFX project. When I use valueProperty().addListener(new ChangeListener())
it is action repeated progressively with every click

Here is my controller:

public class Controller {

// some code

@FXML
private ComboBox<String> FruitList;


int count = 1;

public void comboAction() {
FruitList.valueProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
System.out.println("Selected value : " + newValue);
}
});
//count number of select actions
System.out.println("Selection number: " + count++);

}
}


My FXML file:

<!--some code-->

<ComboBox fx:id="FruitList" onAction="#comboAction" layoutX="22.0" layoutY="212.0" prefHeight="25.0" prefWidth="234.0" promptText="Choose the current month">
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="Apple" />
<String fx:value="Orange" />
<String fx:value="Pear" />
</FXCollections>
</items>
</ComboBox>

<!--some code-->


Output result

Selection number: 1

Selected value : Apple

Selection number: 2

Selected value : Pear

Selected value : Pear

Selection number: 3

Selected value : Orange

Selected value : Orange

Selected value : Orange

Selection number: 4

Selected value : Apple

Selected value : Apple

Selected value : Apple

Selected value : Apple

Selection number: 5 Selected value : Pear

Selected value : Pear

Selected value : Pear

Selected value : Pear

Selected value : Pear

Selected value : Pear

Answer

If you take a look on the onActionProperty:

The ComboBox action, which is invoked whenever the ComboBox value property is changed.

So when you do this:

<ComboBox fx:id="FruitList" onAction="#comboAction" ...>

The comboAction() method will be executed every time whenever the value is changed.

But in this method you add a new (and every time additional) listener to the valueProperty which listener will be also executed when the value will change next time. And again, and again and again. So on every value change you will have one additional listener.

Obvious fix to take the listener method body and insert it into the outer method body without adding a new listener:

public void comboAction() {
    System.out.println("Selected value : " + FruitList.getValue());
}