Data binding 如何创建具有动态列数的表
Thare是一个位于javaFX文档页面的页面。本例描述了如果您有一些sertain java类,如何创建tableView,该类可以告诉您将拥有哪些列。(在本例中是Person类) 但是,如果我没有任何特定的类,并且列的数量可以随时变化,该怎么办? 就我而言,我有这样的数据结构:Data binding 如何创建具有动态列数的表,data-binding,tableview,javafx-2,Data Binding,Tableview,Javafx 2,Thare是一个位于javaFX文档页面的页面。本例描述了如果您有一些sertain java类,如何创建tableView,该类可以告诉您将拥有哪些列。(在本例中是Person类) 但是,如果我没有任何特定的类,并且列的数量可以随时变化,该怎么办? 就我而言,我有这样的数据结构: class TableData{ List<Row> rows; //A list with all my rows i need to have in my table } class Ro
class TableData{
List<Row> rows; //A list with all my rows i need to have in my table
}
class Row{
List<Column> columns; //Cells\Columns for every row.
}
class Column{
Attribute attr; //Each column - is somethig like a wrapper for the real data i need to show in a cell;
}
class Attribute{ //My precues data
String name;
SupportingInfo info;
}
class SupportingInfo{//Some supporting fields...
String name;
String value;
//...etc....
}
类表数据{
列出行;//一个包含我需要在表中包含的所有行的列表
}
班级排{
列出列;//每行的单元格\列。
}
类列{
属性attr;//每列-都像是我需要在单元格中显示的真实数据的包装器;
}
类属性{//My precues data
字符串名;
支持信息化;
}
类支持信息{//某些支持字段。。。
字符串名;
字符串值;
//……等等。。。。
}
所以,我的情况和我的非常相似。
唯一不同的是,上面案例中的数据没有与javaFX表中的表示绑定(因此,即使有人会在tableView中进行额外的控件来编辑此数据,具有该数据的实际对象也永远不会知道它),因为它(数据)像一些字符串一样进入表中,而不像一些对象
所以,我需要的是将数据推送到表中(如:table.setItems(tableData)),设置一些集合工厂,让用户能够编辑数据,并将这些编辑后的数据保存在我的tableData对象中
以下是我为实现这一目的而编写的一些代码:
//prepare my table
private void createTableHeader(TableView table, List<Attribute> ias) {
int i = 0;
for (final Attribute ia : ias) {
final int j = i;
i++;
TableColumn tc = new TableColumn(ia.getName());
tc.setSortable(true);
tc.setCellValueFactory(new Callback<CellDataFeatures<List<Attribute>, String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(CellDataFeatures<List<Attribute>, String> arg0) {
if(arg0.getValue().get(j).getSupportingInfo() == null){
arg0.getValue().get(j).setSupportingInfo(new SupportingInfo());
}
return new SimpleObjectProperty(arg0.getValue().get(j),"value");
}
});
table.getColumns().add(tc);
}
}
//loading some data to my tableView
private void createTableBody(TableView curTable, List<Row> rows) {
ObservableList<List<Attribute>> data = FXCollections.observableArrayList();
for (Row row : rows) {
data.add(row.getColumns());
}
curTable.setItems(data);
}
//this one is to define some extra controls for editing data in a table by users
private void makeCellFactory(TableColumn curTableCol, final Attribute templateIa, final Document doc) {
curTableCol.setCellFactory(new Callback<TableColumn, TableCell>() {
public TableCell call(TableColumn p) {
final EditingCell cell = new EditingCell(templateIa, doc);
return cell;
}
});
}
//准备我的表格
私有void createTableHeader(表视图表,列表ias){
int i=0;
for(最终属性ia:ias){
最终int j=i;
i++;
TableColumn tc=新的TableColumn(ia.getName());
tc.可设置可编程(真);
tc.setCellValueFactory(新回调(){
@凌驾
公共ObservableValue调用(CellDataFeatures arg0){
if(arg0.getValue().get(j.getSupportingInfo()==null){
arg0.getValue().get(j).setSupportingInfo(新的SupportingInfo());
}
返回新的SimpleObject属性(arg0.getValue().get(j),“value”);
}
});
table.getColumns().add(tc);
}
}
//将一些数据加载到我的tableView
私有void createTableBody(TableView可压缩,列表行){
ObservableList data=FXCollections.observableArrayList();
用于(行:行){
data.add(row.getColumns());
}
可缩减。设置项(数据);
}
//这是定义一些额外的控件,用于用户编辑表中的数据
私有void makeCellFactory(TableColumn curTableCol、最终属性templateIa、最终文档文档){
curTableCol.setCellFactory(新回调(){
公共TableCell调用(TableP列){
最终编辑单元=新编辑单元(模板、文档);
返回单元;
}
});
}
但是,结果是,我的表中只有空行,可以单击某些单元格并接收表编辑控件。但by表中没有默认值;
我的代码哪里做错了?好的,我找到了一个解决方案:
ts.setCellFactory应如下所示:
tc.setCellValueFactory(new Callback<CellDataFeatures<List<Attribute>, SupportingInfo>, ObservableValue<Attribute>>() {
@Override
public ObservableValue<Attribute> call(CellDataFeatures<List<Attribute>, SupportingInfo> arg0) {
return new SimpleObjectProperty(arg0.getValue().get(j),"value",arg0.getValue().get(j));
}
});
tc.setCellValueFactory(新回调(){
@凌驾
公共ObservableValue调用(CellDataFeatures arg0){
返回新的SimpleObject属性(arg0.getValue().get(j),“value”,arg0.getValue().get(j));
}
});
此外,捕获新值并将传入数据放入表中需要此代码:
tc.setOnEditCommit(new EventHandler<CellEditEvent<List<Attribute>, Attribute>>() {
@Override
public void handle(CellEditEvent<List<Attribute>, Attribute> t) { t.getTableView().getItems().get(t.getTablePosition().getRow()).get(j).setSupportingInfo(t.getNewValue().getSupportingInfo());
}
});
tc.setOnEditCommit(新的EventHandler(){
@凌驾
公共无效句柄(CellEditEvent t){t.getTableView().getItems().get(t.getTablePosition().getRow()).get(j).setSupportingInfo(t.getNewValue().getSupportingInfo());
}
});
我试图将您的代码放入一个类中并进行编译,但没有成功。Row#getColumns应返回右侧列的列表,但在#createTableBody中,它被添加到ObservableList中。也许使用2D属性数组可以简化事情?createTableHeader方法中的表列作为makeCellFactory参数传递?如果是这样的话,就很自然地只期望最后的行为,因为我相信TableColumn只能有一个cellFactory。如果设置两次,最后一个将是有效的