上一章中,我们介绍了如何动态添加数据,以及对TableView的数据进行编辑等功能。
这一章中,我们将会学习如何使用自定的Cell来实现大家自己想实现的TableView。
示例代码还是接上一章的代码来看,假设,我们需要添加一列为"工作进度",并使用一个进度条来表示工作进度。
首先,我们需要在数据模型PersonData中添加一个Double属性来表示进度条的值:
public SimpleDoubleProperty mProgressProperty = new SimpleDoubleProperty();
public void setProgress(double mProgress){
mProgressProperty.set(mProgress);
}
public double getProgress(){
return mProgressProperty.get();
}
接下来,我们就要创建"工作进度"的TableColumn,然后给它设定CellFactory和CellValueFactory(一个用于定义Cell视图,一个用于定义Cell的值)。
TableColumn progressCol = new TableColumn("工作进度");
progressCol.setPrefWidth(colWidth);
progressCol.setCellFactory(ProgressBarTableCell.forTableColumn());
progressCol.setCellValueFactory(new PropertyValueFactory<>("progress"));
记得将TableColumn加入到TableView中。这里我们使用了自带的ProgressBarTableCell,当然自带的还有TextFieldTableCell用于编辑数据等。
运行效果如下:
上面是使用的自带的CellFactory,通常情况下应该是足够我们用的,但很多时候我们需要显示一些自定义的东西,那么就需要自定义Cell了。
首先我们要继承TableCell来实现他的方法:
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
/**
* Created by wingmei on 2017/4/27.
*/
public class ButtonTableCell extends TableCell<PersonData,String> {
private Button submitBtn = new Button("提交记录");
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if(!empty){
setGraphic(submitBtn);
}else {
setGraphic(null);
}
}
}
然后我们新建一个TableColumn来用于放置我们的"提交记录"Cell:
TableColumn submitCol = new TableColumn("提交记录");
submitCol.setCellFactory(new Callback<TableColumn, TableCell>() {
@Override
public TableCell call(TableColumn param) {
return new ButtonTableCell();
}
});
submitCol.setPrefWidth(colWidth);
运行效果如下所示:
这样我们就将按钮放入了TableCell中,实现了我们的自定义Cell了。
当然,做到这里,大家可能会有疑问,我们点击"提交记录"按钮,如何知道我们点击的是哪一项呢?在这里我们就要将Button的事件和TableRow关联起来了。
下面我们先修改ButtonTableCell,给它增加一个Listener,然后将当前Cell的Item传递进去:
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
/**
* Created by wingmei on 2017/4/27.
*/
public class ButtonTableCell extends TableCell<PersonData,String> {
private Button submitBtn = new Button("提交记录");
private ButtonTableCellActionListener mListener;
public ButtonTableCell(ButtonTableCellActionListener listener){
mListener = listener;
submitBtn.setOnAction(event -> {
if(mListener != null){
mListener.onClick((PersonData) getTableRow().getItem());
}
});
}
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if(!empty){
setGraphic(submitBtn);
}else {
setGraphic(null);
}
}
public interface ButtonTableCellActionListener {
public void onClick(PersonData data);
}
}
接着,我们在实现的CellFactory中来实现这个Listener的方法:
TableColumn submitCol = new TableColumn("提交记录");
submitCol.setCellFactory(new Callback<TableColumn, TableCell>() {
@Override
public TableCell call(TableColumn param) {
return new ButtonTableCell(new ButtonTableCell.ButtonTableCellActionListener() {
@Override
public void onClick(PersonData data) {
new Alert(Alert.AlertType.INFORMATION,data.getName()).show();
}
});
}
});
submitCol.setPrefWidth(colWidth);
这里我们使用了JavaFX新版API中的对话框Alert,来做提示。
运行效果如下:
这样我们就能在点击提交的同时,得到当前TableRow的数据了。
那么,这一节TableView的自定义CellFactory的使用,就讲解到这里了。
另外,之前还有一点没有讲到的是,TableView使用 table.getSelectionModel().getSelectedIndex()来获取当前TableView的选中项,这也是非常常用的地方。
到现在,TableView的讲解就暂时结束了,以后可能还会继续讲,也可能不会了。但下一章,我们就要开始另外的内容讲解,目前计划是博客一天发一篇,有可能会提前屯好文章,但最后肯定还是一天发一篇,看能坚持多久吧,感谢大家支持。
文章评论
大神,太牛逼了