JavaFx ObservableList的使用详解
原文地址:JavaFx ObservableList的使用详解 | Stars-One的杂货小窝
最近在研究MVVM模式,发现可以将之前写的FxRecyclerView控件改造一下,便是开始尝试,尝试过程中发现了不少坑,但是网上资料不是太全面,这里便写一篇笔记记录一下,以供后来者的学习
注:由于本人使用的是TornadoFx来编写JavaFx项目,所以本文代码是使用Kotlin进行编写,需要有Kotlin基础,阅读前请须知,以免浪费你宝贵的时间
介绍
在MVVM模式火的今天,没想到之前JavaFx已经早有实现,估计现在市面这些都是玩别人剩下的了
这次也是想到了之前的FxRecyclerView控件可以拿MVVM改造一番
网上的资料并不多,仅有少有的一两篇,无奈之下,只得自己啃着官方文档,自己摸索,终于是把基本的使用摸清了
ObservableList
,正如其名,可观察的List,它与List一样,也是个接口(Java的基础知识了..)
官方简短介绍:
A list that allows listeners to track changes when they occur.
大意为当数据改变时,ObservableList可以监听到这些改变,本质上是提供了一个监听器接口ListChangeListener.Change
来进行相关的监听,
怎么监听呢?只需要设置监听器即可
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
两个属性在后面提及,这里稍微留意一下
三种监听类型
从上面的代码中,我们可以看到有几个分支条件,每个分支就是数据发生了某种改变,基本的有三种情况:
- List排列顺序改变
- List中的数据发生改变(数据更新)
- List的数据添加及删除(数据新增或删除)
PS:官方文档说明中,监听的顺序依次为wasPermutated、add/remove、update
下面对这几种情况进行说明
1.排列更新监听
顺序排列更新,对应的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] //降序排列
2.数据更新监听(replace)
这里大家可能会有点疑惑,最上面的代码不是有个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]
3.数据添加与删除监听(add remove)
数据添加和删除就和上面同理了,当我们调用add()
(包括addAll()
)和remove()
方法,对应的wasAdd()
和wasRemove()
方法就会返回true
另外,ObservableList提供了两个List供我们拿到添加的数据和移除的数据
- change.addedSubList 新增的数据列表
- change.removed 被移除的数据列表
补充:from与to
这里大家可能就注意到了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方法说明
- addAll()
- remove(from,to) 移除[from,to)之间的元素,from是包含,to是不包含的,注意与remove监听事件返回的from和to都是相同的
- move(oldIndex,newIndex) 将下标为oldIndex移动至newIndex下标处
补充:移动监听(move)
之前没有找到更新的方法,发现了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]
参考
- JavaFX - 如何处理ObservableList的更改操作_W3Cschool代码实例
- ListChangeListener.Change (JavaFX 8)
- ObservableList (JavaFX 8)
JavaFx ObservableList的使用详解的更多相关文章
- JavaFx TableView疑难详解
TableView是个十分有用的控件,适应性和灵活性非常强,可以对它进行任意的修改,比如界面样式.功能.本文将从一步步提问的方式讲解TableView 创建已知列的TableView 已知列的表格的创 ...
- WordPress代码高亮插件SyntaxHighlighter终极使用详解
子曰: 工欲善其事,必先利其器.作为码农一枚,再加上站长这个已经不再光鲜的称呼,岂能没有一款经济实用.操作简单.而且功能必须强大.样式也必须好看的Wordpress代码高亮插件?!作为一个视代码如生命 ...
- Linq之旅:Linq入门详解(Linq to Objects)
示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...
- 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)
一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...
- EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解
前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...
- Java 字符串格式化详解
Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...
- Android Notification 详解(一)——基本操作
Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...
- Android Notification 详解——基本操作
Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...
- Git初探--笔记整理和Git命令详解
几个重要的概念 首先先明确几个概念: WorkPlace : 工作区 Index: 暂存区 Repository: 本地仓库/版本库 Remote: 远程仓库 当在Remote(如Github)上面c ...
随机推荐
- Windows锁定屏幕然后关闭显示器,可执行程序
有时候我们需要关闭屏幕来休息一下或者在本上写东西,但是屏幕亮着的时候会分心,但是关闭显示器又太麻烦了,所以直接来一个小程序(非微信小程序).还有一种情况,有时候晚上要离开电脑旁了,但是电脑还在做事情, ...
- 如何通过台服流出的服务端自己架设DNF
为达到更好的浏览效果,请点击原文:https://wuter.cn/513.html/ 写在最前 其实我也是dnf忠实粉丝,大概在四年级也就是2008年刚刚开始公测的时候就入坑了,一直持续到高中,目睹 ...
- x264编码demo定制修改介绍
x264编码器,提供了两个demo来验证编码功能:一个是大而全的x264.c,另外一个是简洁版的example.c. 其中,前者demo,可以配置很多编码参数,但太冗长繁杂,对初学者不太友好. 后者 ...
- 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?
==知识梳理== ==重难点梳理== ==今日目标== 1.能够了解什么是可变参数 2.能够了解如何去创建不可变集合 3.能够掌握Stream流的使用 ==知识点== 1.可变参数 2.Stream流 ...
- vue结合element-ui table本地分页
<template> <el-table :data="tableData1.slice((start1-1)*length1,start1*length1)" ...
- MD5,BASE64Encoder加密
package com.cn.peitest; import java.io.UnsupportedEncodingException; import java.security.MessageDig ...
- [leetcode33Search in Rotated Sorted Array]在排序旋转后序列中找目标值
直接上代码 /** * Created by lvhao on 2017/6/30. * Suppose an array sorted in ascending order is rotated a ...
- Redis基础篇(六)数据同步:主从复制
Redis具有高可靠性,体现在两方面: 一是数据尽量少丢失,通过前面介绍的持久化方式AOF和RDB,在宕机时可以恢复数据. 二是服务尽量少中断,通过副本冗余来实现. 今天我们学习的就是通过主从复制实现 ...
- 哎,这让人抠脑壳的 LFU。
这是why哥的第 83 篇原创文章 让人抠脑壳的 LFU 前几天在某APP看到了这样的一个讨论: 看到一个有点意思的评论: LFU 是真的难,脑壳都给我抠疼了. 如果说 LRU 是 Easy 模式的话 ...
- fastjson反序列化漏洞原理及利用
重要漏洞利用poc及版本 我是从github上的参考中直接copy的exp,这个类就是要注入的类 import java.lang.Runtime; import java.lang.Process; ...