JavaFx:如何绑定到非空或空列表?

JavaFx: How to bind to a not null or empty list?

这个有效:

getTableView().itemsProperty().addListener((observableValue, oldVal, newVal) -> button.setDisable(newVal == null || newVal.isEmpty()));

当 tableview 项目为 null 或空时,该按钮被禁用。

我想知道是否有“绑定”解决方案以及如何实施。

button.disableProperty().bind(Bindings.or(Bindings.isNull(getTableView().itemsProperty()), Bindings.isEmpty(getTableView().getItems())));

以上不起作用,因为 itemsProperty 永远不会 null 并且 getItems() 可能为空,导致 Bindings.isEmpty() 失败。

TableViewItemsProperty 是一个简单的 ObservableProperty,它不提供任何专门的功能来跟踪 ObservableList.

中的项目

您需要创建一个 ListProperty,它反过来提供了您可以用于您的目的的 emptyProperty

ListProperty<String> listProperty = new SimpleListProperty<>();;

现在绑定 属性 以观察 TableViewItemsProperty:

listProperty.bind(tableView.itemsProperty());

最后一步只是绑定 Button:

disableProperty
button.disableProperty().bind(listProperty.emptyProperty());

下面是使用 ListView 而不是 TableView 的完整示例。功能是相同的,但就此示例而言,ListView 实施起来更快。

import javafx.application.Application;
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ButtonBindingToList extends Application {

    public static void main(String[] args) {

        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        // **********************************************************************************************
        // Create a basic layout
        // **********************************************************************************************
        VBox root = new VBox(5);
        root.setAlignment(Pos.TOP_CENTER);
        root.setPadding(new Insets(10));

        // **********************************************************************************************
        // Creat the ListView
        // **********************************************************************************************
        ListView<String> listView = new ListView<>();

        // **********************************************************************************************
        // Create a Button to add items to the list (will always be enabled).
        // **********************************************************************************************
        Button btnAdd = new Button("Add item");
        btnAdd.setOnAction(event -> listView.getItems().add("Added item #" + listView.getItems().size()));

        // **********************************************************************************************
        // Create button to remove the last item in the ListView
        // **********************************************************************************************
        Button btnRemove = new Button("Remove last item");
        btnRemove.setOnAction(event -> listView.getItems().remove(listView.getItems().size() - 1));

        // **********************************************************************************************
        // In order to bind to the emptiness of the ListView, we need to create a ListProperty that
        // is bound to the ListView's itemsProperty
        // **********************************************************************************************
        ListProperty<String> listProperty = new SimpleListProperty<>();
        listProperty.bind(listView.itemsProperty());

        // **********************************************************************************************
        // Now bind the "Remove" button's disable property to the listProperty. This will disable
        // the button as long as the ListView is empty
        // **********************************************************************************************
        btnRemove.disableProperty().bind(listProperty.emptyProperty());

        root.getChildren().addAll(listView, btnAdd, btnRemove);

        // **********************************************************************************************
        // Set the Scene for the stage
        // **********************************************************************************************
        primaryStage.setScene(new Scene(root));

        // **********************************************************************************************
        // Configure the Stage
        // **********************************************************************************************
        primaryStage.setTitle("Test Application");
        primaryStage.show();
    }
}