JavaFX高級組件之TableView
- 先整體說說
使用 TableView
控件時,其重點不在於顯示圖形界面,而在於界面上展示數據與後臺數據的動態綁定!
一般使其能夠動態更新需要有兩個條件:
1. 使用 TableView
和 ObservableList<T>
的雙向綁定。ObservableList<T>
是JavaFX結合框架下的實現類。類似於普通集合類,但是它是允許跟蹤更改的列表,可以與 util
包下的集合互相轉換。
2. 使用具有 Property
屬性的數據封裝。
如何在佈局中添加TableView
- 創建
TableView
實例和ObservableList<T>
實例,代碼如下:
- 創建
public TableView<DataEntry> table = new TableView<DataEntry>();
public ObservableList<DataEntry> data = FXCollections.observableArrayList(list);//FXCollection和UnitCollection的轉換
//list爲ArrayList集合,通過FXCollection對象可以實現轉換
Collection和FXCollection的互相轉換:
ArrayList<DataEntry> dataList = new ArrayList<DataEntry>(ObservableList<Data> data);
ObservableList<DataEntry> data = FXCollections.observableArrayList(list);
- 創建
TableColumn
(列實例),綁定數據模型,添加到表格
TableColumn<DataEntry, String> dataNameCol = new TableColumn<DataEntry, String>("Data Name");//定義列
dataNameCol.setMinWidth(100);//設置列的最小寬度
dataNameCol.setCellValueFactory(new PropertyValueFactory<>("dataName"));//將列與數據模型中的數據屬性綁定
table.setItems(data);//table 和 ObservableList 數據綁定
table.getColumns().addAll(selectedCol,dataNameCol, dataValueCol);//綁定創建的列到表格
至此,一個表格視圖就快要創建完成了,還有最重要的一點,特殊的數據封裝!一下代碼爲本例中 DataEntry
數據模型的實現:
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleStringProperty;
public class DataEntry {
private final SimpleStringProperty dataName;
private final SimpleDoubleProperty dataValue;
public DataEntry(String dataName, Double dataValue) {
this.dataName = new SimpleStringProperty(dataName);
this.dataValue = new SimpleDoubleProperty(dataValue);
}
public String getDataName() {
return dataName.get();
}
public void setDataName(String dName) {
dataName.set(dName);
}
public SimpleStringProperty dataNameProperty(){
return dataName;
}
public Double getDataValue() {
return dataValue.get();
}
public void setDataValue(Double dValue) {
dataValue.set(dValue);
}
public SimpleDoubleProperty dataValueProperty(){
return dataValue;
}
}
在確保以上條件正確的情況下,一個可以動態更新數據的表格就完成了。效果如下圖:
如上圖,在表格中添加類似單選框的組件是怎麼做到的呢?
自定義表格單元格
- 使單元格可編輯,代碼如下:
dataNameCol.setCellFactory(TextFieldTableCell.<DataEntry>forTableColumn());//將 dataNameCol 列的單元格定義爲 TextFieldTableCell
dataNameCol.setOnEditCommit((CellEditEvent<DataEntry,String> t) -> { //創建單元格被修改事件
((DataEntry) t.getTableView().getItems().get(t.getTablePosition().getRow())).setDataName(t.getNewValue()); //將新的值賦給獲取到的單元格
});
- 在單元中加入
CheckBox
單選框:
TableColumn<DataEntry,Boolean> selectedCol = new TableColumn<DataEntry, Boolean>("Check");//定義列
selectedCol.setMinWidth(50);
selectedCol.setCellValueFactory(new PropertyValueFactory<>("selected"));
selectedCol.setCellFactory(new Callback<TableColumn<DataEntry, Boolean>, TableCell<DataEntry, Boolean>>() {
@Override
public TableCell<DataEntry, Boolean> call(
TableColumn<DataEntry, Boolean> param) {
CheckBoxTableCell<DataEntry, Boolean> cell = new CheckBoxTableCell<>();
cell.setAlignment(Pos.CENTER);
return cell;
}
});
selectedCol.setOnEditCommit((CellEditEvent<DataEntry,Boolean> t) -> {
((DataEntry) t.getTableView().getItems().get(t.getTablePosition().getRow())).setSelected(t.getNewValue());
});
當然在數據模型封裝中,也要爲 單選框 這一列建立一個 SimpleBooleanProperty 的綁定屬性。
private SimpleBooleanProperty selected = new SimpleBooleanProperty(false);
public Boolean getSelected() {
return selected.get();
}
public void setSelected(Boolean flag) {
selected.set(flag);
}
public SimpleBooleanProperty selectedProperty(){
return selected;
}
效果圖