TableView 的 ItemProperty() 的侦听器不会失效(javafx)?

Vin*_*ens 1 java javafx

我试图让程序在 TableView 中添加一行时做出反应,但 ItemProperty 在列表更改时不会通知侦听器。

我认为这可能是因为我没有“设置”项目(作为新的不同列表)而只是添加到列表中,但我不确定。

我在 stackoverflow 上找到了这个,但我不认为这是同一个问题(或者至少该解决方案对我不起作用)。

有什么方便的方法来解决这个问题吗?

最小可重现示例:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Sla*_*law 6

问题方案

您要将 添加InvalidationListener到属性中items,该属性是 的实例ObjectProperty。该属性上的侦听器不会知道它所包含的值何时发生某些情况(它甚至不知道其值是否/何时可观察)。您需要将侦听器添加到其ObservableList本身。

// javafx.beans.Observable
integerTableView
    .getItems()
    .addListener((Observable e) -> System.out.println("Items invalidated!"));
Run Code Online (Sandbox Code Playgroud)

列表更改监听器

请注意,对列表进行任何类型的更改都会触发InvalidationListeneron an ,并且您不会知道进行了哪种类型的更改。ObservableList如果您想要有关更改的详细信息,那么您应该使用ListChangeListener.

// javafx.collections.ListChangeListener
integerTableView.getItems().addListener((ListChangeListener<Integer>) c -> {
  while (c.next()) {
    // process change (see documentation for more info)
  }
});
Run Code Online (Sandbox Code Playgroud)