TableView 中的自定义复选框
Custom CheckBox in TableView
我想使用 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;
}
}
主要class:
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;
});
CheckBoxTableCell 为您完成所有繁重的工作,只需要您的 Person class 的一点帮助,它应该 use/expose 属性(相对于仅具有 getters/setters 的普通字段)。然后使用 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();
}
....
配置cell/Value/Factory的列:
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;
}
我想使用 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;
}
}
主要class:
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;
});
CheckBoxTableCell 为您完成所有繁重的工作,只需要您的 Person class 的一点帮助,它应该 use/expose 属性(相对于仅具有 getters/setters 的普通字段)。然后使用 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();
}
....
配置cell/Value/Factory的列:
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;
}