原文地址: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]