从零开始学习JavaFX(16) 控件篇之TableView(3)

上一章中,我们介绍了如何动态添加数据,以及对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,然后给它设定CellFactoryCellValueFactory(一个用于定义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的讲解就暂时结束了,以后可能还会继续讲,也可能不会了。但下一章,我们就要开始另外的内容讲解,目前计划是博客一天发一篇,有可能会提前屯好文章,但最后肯定还是一天发一篇,看能坚持多久吧,感谢大家支持。

发表评论

电子邮件地址不会被公开。