TableView中的自定义CheckBox

时间:2018-01-05 18:37:58

标签: java javafx cell factory

我想使用setStyle方法将自定义样式应用于TableView的CheckBox,但我不能这样做。我试图在setCellFactory内创建一个CheckBox而不管CheckBoxTableCell,但在这种情况下,ObservableList<Person>中的值不再更新。

我的代码如下:

public class Person {

    private String name;
    private boolean accepted;

    public Person(String name, boolean accepted) {
        this.name = name;    
        this.accepted = accepted;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public boolean isAccepted() {
        return accepted;
    }
    public void setAccepted(boolean accepted) {
        this.accepted = accepted;
    }
}

主要班级:

import javafx.application.Application;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class TableViewWithCheckBox extends Application {
    @Override
    public void start(Stage stage) {
        TableView<Person> table = new TableView<>();

        // Editable
        table.setEditable(true);
        TableColumn<Person, String> fullNameCol = new TableColumn<>("Name");
        TableColumn<Person, Boolean> acceptedCol = new TableColumn<>("Accepted");

        // NAME
        fullNameCol.setCellValueFactory(new PropertyValueFactory<>("name"));
        fullNameCol.setCellFactory(TextFieldTableCell.<Person> forTableColumn());
        fullNameCol.setMinWidth(200);

        // ACCEPTED
        acceptedCol.setCellValueFactory((CellDataFeatures<Person, Boolean> param) -> {
            Person person = param.getValue();           
            SimpleBooleanProperty booleanProp = new SimpleBooleanProperty(person.isAccepted());

            booleanProp.addListener(
                    (ObservableValue<? extends Boolean> observable,
                            Boolean oldValue, Boolean newValue) -> {
                        person.setAccepted(newValue);
                    });
            return booleanProp;
        });

        acceptedCol.setCellFactory((TableColumn<Person, Boolean> p) -> {
            CheckBoxTableCell<Person, Boolean> cell = new CheckBoxTableCell<>();
            cell.setAlignment(Pos.CENTER);
            return cell;
        });

        ObservableList<Person> list = getPersonList();
        table.setItems(list); 
        table.getColumns().addAll(fullNameCol, acceptedCol);

        StackPane root = new StackPane();
        root.setPadding(new Insets(5));
        root.getChildren().add(table);

        Scene scene = new Scene(root, 300, 300);
        stage.setScene(scene);
        stage.show();
    }

    private ObservableList<Person> getPersonList() { 
        Person person1 = new Person("John White", true);
        Person person2 = new Person("Kevin Land", false);
        Person person3 = new Person("Rouse Hill", true); 
        ObservableList<Person> list = FXCollections.observableArrayList(person1, person2, person3);
        return list;
    }
}

带有自定义CheckBox但不更新可观察列表的代码:

    acceptedCol.setCellFactory((TableColumn<Person, Boolean> success) -> {
        TableCell<Person, Boolean> cell = new TableCell<Person, Boolean>(){                
            @Override
            public void updateItem(Boolean item, boolean empty) {
                super.updateItem(item, empty);
                if(empty || item == null){
                    setGraphic(null);   
                } else {
                    CheckBox myCheckBox = new CheckBox();
                    myCheckBox.getStyleClass().add("myPersonalCheckBoxStyle");
                    myCheckBox.setSelected(item);
                    setGraphic(myCheckBox);                      
                }
            }
        };         
        return cell;
    });    

1 个答案:

答案 0 :(得分:0)

CheckBoxTableCell为您完成所有繁重工作,只需要您的Person类的一些帮助,它应该使用/公开属性(仅与具有getter / setter的普通字段)。然后使用acceptedProperty配置列,并将自定义样式应用于单元格。

在代码段中:

public class Person {

    private BooleanProperty accepted;

    public Person(String name, boolean single) {
        this.accepted = new SimpleBooleanProperty(single);
        ... 
    }

    public BooleanProperty acceptedProperty() {
        return accepted;
    }

    public boolean isAccepted() {
        return acceptedProperty().get();
    }

    ....

使用单元格/值/工厂配置列:

acceptedCol.setCellValueFactory(new PropertyValueFactory<>("accepted"));

acceptedCol.setCellFactory((TableColumn<Person, Boolean> p) -> {
    CheckBoxTableCell<Person, Boolean> cell = new CheckBoxTableCell<>();
    cell.getStyleClass().add("custom-cell");
    cell.setAlignment(Pos.CENTER);
    return cell;
});

一些自定义样式:

/**
 * Just want to see an effect, doesn't matter what
 */
.custom-cell > .check-box {
    -fx-background-color: blue;
}
.custom-cell > .check-box:selected {
    -fx-background-color: red;
}