代码之家  ›  专栏  ›  技术社区  ›  Zuri

TableView中的自定义复选框

  •  -1
  • Zuri  · 技术社区  · 7 年前

    我想使用 setStyle 方法 CheckBox 但我做不到。我尝试在 setCellFactory 不管 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;
        }
    }
    

    和自定义的代码 复选框 但这并不能更新可观察列表:

        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 回复  |  直到 7 年前
        1
  •  0
  •   kleopatra Aji kattacherry    7 年前

    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;
    }