将arraylist size属性绑定到Java FX按钮

big*_*ord 0 javafx arraylist observable

假设我在同一控制器中有一个可观察的列表和一个按钮

private ObservableList<NameItem> _selectedList = _database.getONameList();

@FXML
private Button nextButton;
Run Code Online (Sandbox Code Playgroud)

我如何做到只有在ObservableList大于0时才启用按钮,否则将其禁用?我可以使用绑定属性来设置它吗?

我尝试使用此:https : //stackoverflow.com/a/38216335/5709876

但是它对我没有用..

Zep*_*hyr 5

实际上,只需几个简单的Bindings就可以很容易地做到这一点。

首先,您要创建一个IntegerBinding绑定到您的大小的ObservableList

IntegerBinding listSize = Bindings.size(_selectedList);
Run Code Online (Sandbox Code Playgroud)

然后创建一个新BooleanBinding的绑定到listSize绑定是否大于0:

BooleanBinding listPopulated = listSize.greaterThan(0);
Run Code Online (Sandbox Code Playgroud)

现在,您需要做的就是使用方法将按钮的绑定disablePropertylistPopulated属性的相反位置not()(因为如果列表中有项目,您实际上要传递给按钮的):listPopulatedtruefalsedisableProperty

button.disableProperty().bind(listPopulated.not());
Run Code Online (Sandbox Code Playgroud)

这是一个快速的MCVE演示:

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.binding.IntegerBinding;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        // Simple interface
        VBox root = new VBox(5);
        root.setPadding(new Insets(10));
        root.setAlignment(Pos.CENTER);

        // Create an empty ObservableList
        ObservableList<String> list = FXCollections.observableArrayList();

        // Create a binding to extract the list's size to a property
        IntegerBinding listSizeProperty = Bindings.size(list);

        // Create a boolean binding that will return true only if the list has 1 or more elements
        BooleanBinding listPopulatedProperty = listSizeProperty.greaterThan(0);

        // Create the button we want to enable/disable
        Button button = new Button("Submit");

        // Bind the button's disableProperty to the opposite of the listPopulateProperty
        // If listPopulateProperty is false, the button will be disabled, and vice versa
        button.disableProperty().bind(listPopulatedProperty.not());

        // Create another button to add an item to the list, just to demonstrate the concept
        Button btnAddItem = new Button("Add Item");
        btnAddItem.setOnAction(event -> {
            list.add("New Item");
            System.out.println(list.size());
        });

        // Add the buttons to the layout
        root.getChildren().addAll(btnAddItem, button);

        // Show the Stage
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,“提交”按钮被禁用,直到您ObservableList使用“添加项目”按钮将项目添加到中。

编辑:正如卢卡斯在下面的评论中很好地指出的那样,这些绑定也可以全部链接在一起以简化事情(这两种方法同等有效;这取决于您发现的内容是否更易读,实际上):

button.disableProperty().bind(Bindings.size(list).greaterThan(0).not())
Run Code Online (Sandbox Code Playgroud)

另一种方法

执行此操作的另一种方法是使用a ListChangeListener,在列表更改时启用或禁用按钮:

    list.addListener((ListChangeListener<String>) c -> {
        // If the size of the list is less than 1, disable the button; otherwise enable it
        button.setDisable(c.getList().size() < 1);
    });
Run Code Online (Sandbox Code Playgroud)

这实际上与第一种方法具有完全相同的作用,但是您需要自己设置按钮的初始状态,然后侦听器才能为您更新按钮的状态。

  • +1请注意,由于目标是在“ ObservableList”为空时禁用“ Button”,因此另一个选择是将“ disableProperty”直接绑定到[`Bindings.isEmpty(ObservableList)`](https ://docs.oracle.com/javase/10/docs/api/javafx/beans/binding/Bindings.html#isEmpty(javafx.collections.ObservableList))。 (4认同)
  • 不错且非常详细的答案,但是您可以添加一个示例,其中所有绑定调用都链接在一起:`button.disableProperty().bind(Bindings.size(list).greaterThan(0).not())` (2认同)
  • 关于问题的标题,您的回答绝不算过大,因为它适用于任何大小限制;) (2认同)