原文地址:JavaFx ObservableList的使用详解 | Stars-One的杂货小窝html
最近在研究MVVM模式,发现能够将以前写的FxRecyclerView控件改造一下,即是开始尝试,尝试过程当中发现了很多坑,可是网上资料不是太全面,这里便写一篇笔记记录一下,以供后来者的学习java
注:因为本人使用的是TornadoFx来编写JavaFx项目,因此本文代码是使用Kotlin进行编写,须要有Kotlin基础,阅读前请须知,以避免浪费你宝贵的时间api
在MVVM模式火的今天,没想到以前JavaFx已经早有实现,估计如今市面这些都是玩别人剩下的了数组
此次也是想到了以前的FxRecyclerView控件能够拿MVVM改造一番oracle
网上的资料并很少,仅有少有的一两篇,无奈之下,只得本身啃着官方文档,本身摸索,终因而把基本的使用摸清了学习
ObservableList
,正如其名,可观察的List,它与List同样,也是个接口(Java的基础知识了..)测试
官方简短介绍:
A list that allows listeners to track changes when they occur.code
大意为当数据改变时,ObservableList能够监听到这些改变,本质上是提供了一个监听器接口ListChangeListener.Change
来进行相关的监听,htm
怎么监听呢?只须要设置监听器便可对象
val observableList = observableListOf(0,1,2,3) observableList.onChange { change -> while (change.next()) { when { change.wasPermutated() -> println("permutated (${change.from} ,${change.to})") change.wasReplaced() -> println("replace (${change.from} ,${change.to})") else -> { when { change.wasAdded() -> println("add (${change.from} ,${change.to})") change.wasRemoved() -> println("remove (${change.from} ,${change.to})") change.wasUpdated() -> println("update (${change.from} ,${change.to})") } } } } }
官方的使用中,必需要求咱们在监听以前调用next方法,其返回false表示当前已是最后一次改变
wasPermutated()
这种方法都是返回的boolean值,当数据发生对应符合的变化,各自对应的方法会返回true
change.from
和change.to
两个属性在后面说起,这里稍微留意一下
从上面的代码中,咱们能够看到有几个分支条件,每一个分支就是数据发生了某种改变,基本的有三种状况:
PS:官方文档说明中,监听的顺序依次为wasPermutated、add/remove、update
下面对这几种状况进行说明
顺序排列更新,对应的change.wasPermutated()
,其返回值为boolean值,当ObservableList的顺序发生变化(即进行了排序操做),此方法就会返回为true
fun main() { val observableList = observableListOf(0,1,2,3) println(observableList) observableList.onChange { change -> while (change.next()) { when { change.wasPermutated() -> println("permutated (${change.from} ,${change.to})") change.wasReplaced() -> println("replace (${change.from} ,${change.to})") else -> { when { change.wasAdded() -> println("add (${change.from} ,${change.to})") change.wasRemoved() -> println("remove (${change.from} ,${change.to})") change.wasUpdated() -> println("update (${change.from} ,${change.to})") } } } } } observableList.sortBy { it } println(observableList) observableList.sortByDescending { it } println(observableList) }
对应的输出结果为:
[0, 1, 2, 3] //源数组 permutated (0 ,4) //回调监听器中的方法 [0, 1, 2, 3] //升序排列 permutated (0 ,4) [3, 2, 1, 0] //降序排列
这里你们可能会有点疑惑,最上面的代码不是有个wasUpdated()
方法吗,这里怎么标的是replace
?
我本身研究的时候,也是很奇怪...官方的那个wasUpdated()
方法没有找到对应的回调方式,照理说我更新了数组中的一个数据,这个wasUpdated()
应该返回的是true,可是实际测试的时候根本没有,反而是wasReplaced()
返回了true
//上面省略相关代码... //JavaFx对应是set(index,element)方法 observableList[1] = 12 //下标为1的对象更新为12 println(observableList)
输出结果:
[0, 1, 2, 3] replace (1 ,2) [0, 12, 2, 3]
数据添加和删除就和上面同理了,当咱们调用add()
(包括addAll()
)和remove()
方法,对应的wasAdd()
和wasRemove()
方法就会返回true
另外,ObservableList提供了两个List供咱们拿到添加的数据和移除的数据
这里你们可能就注意到了change
对象的from
和to
这两个属性的区别了
本质上,
ObservableList
里面定义的from
和to
这两个表明开始下标和结束下标,在数据发生改变的时候,记录了是哪几条数据发生了改变,以后提供给咱们,咱们在ObservableList.change
监听器方法中就能够使用这两个变量来进行相关的逻辑操做
如下是官方对from的说明:
If wasAdded is true, the interval contains all the values that were added. If wasPermutated is true, the interval marks the values that were permutated. If wasRemoved is true and wasAdded is false, getFrom() and getTo() should return the same number - the place where the removed elements were positioned in the list.
注意重点:若是是数据移除操做,返回的from和to数值是相同的
以前没有找到更新的方法,发现了ObservableList有move的方法,没想到这个在ObservableList中实际上是先作remove操做,以后再作add操做
//代码与上面的一致,已省略 //将下标1的数据移动到下标3的位置 observableList.moveAt(1,3) println(observableList)
输出结果:
[0, 1, 2, 3] remove (1 ,1) add (3 ,4) [0, 2, 3, 1]