Kotlin编写JavaFX的顺滑之数据控件(二)表视图TableView基础深入浅出

并不神秘的Callback<P, R>

书接上回,简单几步,就能把一个对象列表显示为一个表格(每个对象一行,指定的属性为一列)。

  1. 定义行对应的数据结构,构成一个被观察的列表。
  2. 定义所有要显示的列,并逐一添加到表视图,添加顺序为从左往右的显示顺序。
  3. 将数据集合赋予给表视图的项集合。
  4. 将表视图实例添加用户界面容器中。
  5. 构造变更数据集合的用户界面和功能对表格进行操作。

这中间最为重要的就是构造列。

列的构造

val nameColumn= TableColumn<Person, String>("Name").apply {
            cellValueFactory = PropertyValueFactory<Person, String>("name")
        }

列对象有两个类型参数,第一个是行所对应的数据结构,这个类型与表视图的类型参数相同,第二个是当前列对应的属性的类型。

JavaFX的文档是这么说的:

TableColumn<S, T> 
Type parameters:
<S> – The type of the TableView generic type (i.e. S == TableView<S>) 
<T> – The type of the content in all cells in this TableColumn.

这里利用Kotlin的扩展函数apply,设置了一个参数cellValueFactory,这个参数的类型很有意思:

public class PropertyValueFactory<S,T> implements Callback<CellDataFeatures<S,T>, ObservableValue<T>> 
{
// ...
}

Callback接口

Callback接口是Java语言早期的典型特色,因为那时候没有lambda语法,函数化编程还没有开始在Java中实现。

@FunctionalInterface
public interface Callback<P,R> {
    /**
     * The <code>call</code> method is called when required, and is given a
     * single argument of type P, with a requirement that an object of type R
     * is returned.
     *
     * @param param The single argument upon which the returned value should be
     *      determined.
     * @return An object of type R that may be determined based on the provided
     *      parameter value.
     */
    public R call(P param);
}

这个其实就定义了一个可以被调用的函数:其参数和返回值对应于接口的两个类型参数PR

回到cellValueFactory

我们知道,Kotlin对Java还做了一个属性访问的语法糖,也就是setXXXXgetXXXX可以简单的用xXXXX的形式访问。

setXXXX方法可以访问(有定义并且可见),是一个可写属性,也就是属性可以作为左值(放在等号的左边);当只有getXXXX方法时,是一个只读属性,不能作为左值。

这里的

cellValueFactory = PropertyValueFactory<Person, String>("name")

实际就是调用函数setCellValueFactory,参数就是右边的这个Callback的子类。

那么很简单,我们可以自己调用这个函数,并利用Kotlin的语法糖,写成:

 setCellValueFactory {
     SimpleStringProperty(it.value.name)
 }

这就很简洁很强大了。

这里的it的类型为:TableColumn.CellDataFeatures<Person, String>,这个内部类的value属性范围当前行对应的对象。返回值(也就是call函数的返回值为ObservableValue<T>

只要符合这个输出就很好。

更加灵活的表视图

有了前面对源码深入浅出的简单分析和Kotlin语法糖的使用,我们可以很容易实现一些稍微复杂的、更加灵活的表视图产生方式。

替代MapValueFactory<T>

JavaFX还帮我们实现了一个更加灵活的对象表达方式,就是将每一行用一个字典类Map来表达的形式。
在这里插入图片描述
使用这个很简单,但是我们也可以不用。

 setCellValueFactory {
     SimpleStringProperty(it.value.get("name"))
 }

做数据处理和检查

在这个函数里面,就能够对数据进行检查,并做一些处理。

setCellValueFactory { cellData ->
    var name = cellData.value.name
    if (name[0].isLowerCase()) {
        name = name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
    }
    SimpleStringProperty(name)
}

虚拟列

如此,对于已经定义好的Person类,也很容易增加虚拟的列。不再赘述。

结论

利用表视图来展示一系列数据时,表视图获取某行某列的值利用一个函数接口。采用Kotlin的语法糖,很容易增加灵活的返回值的方式。

只能说吧, Java(pre 8)虽好,Kotlin更强大。

posted @ 2023-02-18 20:58  大福是小强  阅读(34)  评论(0编辑  收藏  举报  来源