I'm trying to let a program react when a line is added in a TableView, but the ItemProperty doesn't notify the listeners when the list is changed.
I think that might be because I don't 'set' the items (as a new different list) but just add to the list, but I'm not sure.
I found this on stackoverflow, but I don't think it's the same problem (or at least the solution didn't work for me).
Is there any convenient way to fix this?
minimal reproducible example:
import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.Random;
public class Main extends Application {
private static Random RG = new Random();
@Override
public void start(Stage stage) throws Exception {
VBox vBox = new VBox();
TableView<Integer> integerTableView = new TableView<>();
TableColumn<Integer, Integer> testColumn = new TableColumn<>("test");
testColumn.setCellValueFactory(i -> new SimpleIntegerProperty(i.getValue().intValue()).asObject());
integerTableView.getColumns().add(testColumn);
Button button = new Button("Add random number");
button.setOnAction(e -> {
integerTableView.getItems().add(RG.nextInt());
});
vBox.getChildren().addAll(integerTableView, button);
Scene scene = new Scene(vBox);
stage.setScene(scene);
stage.show();
integerTableView.itemsProperty().addListener(e -> System.out.println("Added item"));
}
public static void main(String[] args) {
launch(args);
}
}
CodePudding user response:
You're adding the InvalidationListener
to the items
property, which is an instance of ObjectProperty
. A listener on that property will not know when something happens to the value it contains (it doesn't even know if/when its value is observable). You need to add the listener to the ObservableList
itself.
integerTableView
.getItems()
.addListener((Observable e) -> System.out.println("Items invalidated!"));
Based on your example code, you'd need to add:
import javafx.beans.Observable;
To your code.
Note if you replace the list (e.g., integerTableView.setItems(newList)
) then you'll need to add a listener to the new list to continue getting notified of the table's items being invalidated.
CodePudding user response:
replace
integerTableView.itemsProperty().addListener(e -> System.out.println("Added item"));}
by this
integerTableView.getItems().addListener((ListChangeListener )(e -> {System.out.println("Added item");}));
!!!! you need to cast lambda (ListChangeListener ) otherwise you will get "reference to addlistener is ambiguous " warning , because there are more listeners for that Class