CheckBoxTableCell选择整列

时间:2017-03-24 13:19:08

标签: javafx-8

无论是否选中,我都无法获取复选框的值。 我无法选择或取消选择CheckBoxTableCell的整个列

enter image description here

// CLASS MODELO

public class Cidade{

    private Integer codigo;
    private String descricao;

    public AAA(Integer codigo, String descricao) {
        super();
        this.codigo = codigo;
        this.descricao = descricao;
    }

    public Integer getCodigo() {
        return codigo;
    }

    public String getDescricao() {
        return descricao;
    }
}

//创建TABLEVIEW的列

TableView tbView = new TableView();
tbView.setEditable(true);

TableColumn colCheck = new TableColumn();
colCheck.setCellFactory(CheckBoxTableCell.forTableColumn(colCheck));

CheckBox cbk = new CheckBox();
cbk.selectedProperty().addListener(new ChangeListener<Boolean>() {
    @Override
    public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
        // TODO Auto-generated method stub
        if (!tbView.getItems().isEmpty())
            if (newValue)
                for (int i = 0; i < tbView.getItems().size(); i++) {

                    ((CheckBox) ((TableColumn) tbView.getColumns().get(0)).getGraphic()).selectedProperty().get();
                }
    }
});

colCheck.setGraphic(cbk);

tbView.getColumns().add(colCheck);

TableColumn colCode = new TableColumn("Codido");
colCode.setCellValueFactory(new PropertyValueFactory("codigo"));

TableColumn colDescricao = new TableColumn("Descricao");
colCode.setCellValueFactory(new PropertyValueFactory("descricao"));

tbView.getColumns().addAll(colCode,colDescricao);

1 个答案:

答案 0 :(得分:1)

CheckBoxTableCell需要selectedStateCallback,这是一个将行索引映射到ObservableValue<Boolean>的函数,用于确定是否应选中复选框。如果提供的可观察值也是WritableValue<Boolean>,则当用户选中或取消选中该复选框时,该值将更新。

最简单的情况是,表的模型具有由复选框表示的布尔属性。但是,情况并非必须如此。例如,您可以创建从表项到布尔属性的映射,并使用该映射中的属性来选中复选框的选定状态:

Map<T, BooleanProperty> checkedRows = new HashMap<>();


checkColumn.setCellFactory(CheckBoxTableCell.forTableColumn(i -> 
    checkedRows.computeIfAbsent(table.getItems().get(i), p -> new SimpleBooleanProperty())));

在这里,您可以使用表格的实际类型替换T

您可能希望确保地图不会保留对不再属于您的表格的项目的引用:

// clear obsolete table items from map:
table.getItems().addListener((Change<? extends T> c) -> {
    if (c.wasRemoved()) {
        c.getRemoved().forEach(checkedRows::remove);
    }
});

现在您只需使用地图检查选中的项目:

T item = ... ;
boolean itemIsChecked = checkedRows.getOrDefault(item, new SimpleBooleanProperty(false)).get() ;

或使用

获取所有选中的项目
List<T> checkedItems = checkedRows.entrySet().stream()
    .filter(e -> e.getValue().get())
    .map(Entry::getKey)
    .collect(Collectors.toList());

您可以使用

选择所有内容
table.getItems().forEach(item -> 
    checkedRows.computeIfAbsent(item , item -> new SimpleBooleanProperty()).set(true));

同样通过设置为false来取消选择。

以下是使用通常的地址簿示例的完整SSCCE:

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Function;

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.ListChangeListener.Change;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class TableViewWithCheckBoxColumn extends Application {

    @Override
    public void start(Stage primaryStage) {
        TableView<Person> table = new TableView<>();
        table.setEditable(true);

        TableColumn<Person, Void> checkColumn = new TableColumn<>();
        table.getColumns().add(checkColumn);

        Map<Person, BooleanProperty> checkedRows = new HashMap<>();

        // clear obsolete table items from map:
        table.getItems().addListener((Change<? extends Person> c) -> {
            if (c.wasRemoved()) {
                c.getRemoved().forEach(checkedRows::remove);
            }
        });

        checkColumn.setCellFactory(CheckBoxTableCell.forTableColumn(i -> 
            checkedRows.computeIfAbsent(table.getItems().get(i), p -> new SimpleBooleanProperty())));

        CheckBox checkAll = new CheckBox();
        checkAll.setOnAction(e -> {
            if (checkAll.isSelected()) {
                table.getItems().forEach(p -> 
                    checkedRows.computeIfAbsent(p, person -> new SimpleBooleanProperty()).set(true));
            } else{
                checkedRows.values().stream().forEach(checked -> checked.set(false));
            }
        });

        checkColumn.setGraphic(checkAll);
        checkColumn.setEditable(true);

        table.getColumns().add(column("First Name", Person::firstNameProperty));
        table.getColumns().add(column("Last Name", Person::lastNameProperty));
        table.getColumns().add(column("Email", Person::emailProperty));

        table.getItems().addAll(
                new Person("Jacob", "Smith", "jacob.smith@example.com"),
                new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
                new Person("Ethan", "Williams", "ethan.williams@example.com"),
                new Person("Emma", "Jones", "emma.jones@example.com"),
                new Person("Michael", "Brown", "michael.brown@example.com") 
        );

        Button verify = new Button("Verify");
        verify.setOnAction(evt -> {
            checkedRows.entrySet().stream().filter(e -> e.getValue().get()).map(Entry::getKey)
            .map(Person::getFirstName).forEach(System.out::println);
        });

        BorderPane root = new BorderPane(table);
        BorderPane.setAlignment(verify, Pos.CENTER);
        BorderPane.setMargin(verify, new Insets(5));
        root.setBottom(verify);

        primaryStage.setScene(new Scene(root, 600, 600));
        primaryStage.show();
    }

    private static <S,T> TableColumn<S,T> column(String title, Function<S, ObservableValue<T>> property) {
        TableColumn<S,T> col = new TableColumn<>(title);
        col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
        return col ;
    }

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

使用通常的Person模型类:

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Person {

    private final StringProperty firstName = new SimpleStringProperty();
    private final StringProperty lastName = new SimpleStringProperty();
    private final StringProperty email = new SimpleStringProperty();

    public Person(String firstName, String lastName, String email) {
        setFirstName(firstName);
        setLastName(lastName);
        setEmail(email);
    }

    public final StringProperty firstNameProperty() {
        return this.firstName;
    }


    public final String getFirstName() {
        return this.firstNameProperty().get();
    }


    public final void setFirstName(final String firstName) {
        this.firstNameProperty().set(firstName);
    }


    public final StringProperty lastNameProperty() {
        return this.lastName;
    }


    public final String getLastName() {
        return this.lastNameProperty().get();
    }


    public final void setLastName(final String lastName) {
        this.lastNameProperty().set(lastName);
    }


    public final StringProperty emailProperty() {
        return this.email;
    }


    public final String getEmail() {
        return this.emailProperty().get();
    }


    public final void setEmail(final String email) {
        this.emailProperty().set(email);
    }

}