JavaFX学习:Observable Collections(观察集合)

news2024/12/25 9:06:58

JavaFX中的观察集合(Observable Collections)继承自Java的集合(Collections)。Java集合提供了List、Map、Set三种集合接口。JavaFX在Java集合基础上派生出可以监听集合内容变化的三种集合接口。接口如下:

ObservableList
ObservableSet
ObservableMap

Java的 集合接口不仅继承Java的List、Map、Set接口,同时还继承JavaFX中的Observable接口。继承关系如下图所示:

 相较于Java中的集合,JavaFX中继承Observable接口的集合有以下新功能:

  • 支持监听失效事件。
  • 支持监听改变事件。可以给继承Observable接口的类注册改变监听器,当集合内容发生变化是进行通知。

ObservableList接口的继承关系如下:

ObservableList接口的addListener()、removeListener()方法注册/注销ListChangeListener事件(ListChangeListener实例),当ObservableList发生改变事件时触发ListChangedListener事件。

void addListener(ListChangeListener<? super E> listener);
void removeListener(ListChangeListener<? super E> listener);

注意,ObservableList接口重写了(Override)Observable接口中的addListener()、removeListener()方法,在Observable接口中,addListener()、removeListener()方法注册/注销InvalidationListener接口。

void addListener(InvalidationListener listener);
void removeListener(InvalidationListener listener);

测试ObservableList注册InvalidationListener接口:

package learnjavafx8.ch03;

import javafx.beans.Observable;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

/**
 * @copyright 2023-2022
 * @package   learnjavafx8.ch03
 * @file      ListInvalidationTest.java
 * @date      2023-06-16 23:13
 * @author    qiao wei
 * @version   1.0
 * @brief     Test invalidation event. Invalidation event includes add, remove, replace and sort.
 * @history
 */
public class ListInvalidationTest {

    public static void main(String[] args) {
        String one = "one";
        
        // Create a list with some elements without changelistener
        ObservableList<String> list = FXCollections.observableArrayList(one, "two");
        System.out.println(list);
        
        // ObservableList implements Observable interface, Register an InvalidationListener to 
        // the list
        list.addListener(ListInvalidationTest::invalidated);

        System.out.println("Before adding element three.------------------------------------");        
        // Add element to list, list fire invalidation event
        list.add("three");
//        System.out.println(list);
        System.out.println("After adding element three------------------------------------\n");
        
        System.out.println("Before adding elements four and five.---------------------------");
        list.addAll("four", "five");
//        System.out.println(list);
        System.out.println("Before adding elements four and five.-------------------------\n");
        
        
        // Replace the element in 0 index
        System.out.println("Before replacing one in index 0.--------------------------------");
        list.set(3, one);
//        System.out.println(list);
        System.out.println("After replacing one in index 0.-------------------------------\n");
    }
    
    /**
     * @class   ListInvalidationTest
     * @date    2023-06-16 23:14
     * @author  qiao wei
     * @version 1.0
     * @brief   Invalidate event. This method is called if an Observable becomes invalid.
     * @param   list The Observable that became invalid.
     * @return  
     * @throws
     */
    public static void invalidated(Observable list) {
        System.out.println("++++++Invalidation event is fired+++++++.");
        System.out.println(list);
    }
}

运行结果:

[one, two]
Before adding element three.------------------------------------
++++++Invalidation event is fired+++++++.
[one, two, three]
After adding element three------------------------------------

Before adding elements four and five.---------------------------
++++++Invalidation event is fired+++++++.
[one, two, three, four, five]
Before adding elements four and five.-------------------------

Before replacing one in index 0.--------------------------------
++++++Invalidation event is fired+++++++.
[one, two, three, one, five]
After replacing one in index 0.-------------------------------


Process finished with exit code 0

测试ObservableList接口注册InvalidationListener接口和ListChangeListener接口。

package learnjavafx8.ch03;

import javafx.beans.Observable;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;

/**
 * @copyright 2023-2022
 * @package   learnjavafx8.ch03
 * @file      ListInvalidationTest01.java
 * @date      2023-06-12 16:42
 * @author    qiao wei
 * @version   1.0
 * @brief     ObservableList实例对invalidated和onChanged事件的处理。注意区别ObservableList中保存的属性的
 *             invalidated和changed事件处理,ObservableList增删Property触发ObservableList的invalidated
 *             事件和changed事件,Property改变自己的值触发Property的invalidated事件和changed事件。
 * @history
 */
public class ListInvalidationTest01 {

    public static void main(String[] args) {
        ObservableList<IntegerProperty> properties = FXCollections.observableArrayList();
        
        // ObservableList添加invalidated事件和changed事件监听器
        properties.addListener(ListInvalidationTest01::onChanged);
        properties.addListener(ListInvalidationTest01::invalidated);
        
        IntegerProperty property01 = new SimpleIntegerProperty(22);        
//        IntegerProperty property02 = new SimpleIntegerProperty(301);
        
        // Property添加invalidated事件监听器,当Property“失效”时触发
        property01.addListener(ListInvalidationTest01::invalidatedForProperty);
//        property02.addListener(ListInvalidationTest01::invalidatedForProperty);
        
        // Property添加changed事件监听器,当属性“改变”时触发
        property01.addListener(ListInvalidationTest01::changedForProperty);
//        property02.addListener(ListInvalidationTest01::changedForProperty);

        // ObservableList添加元素。触发ObservableList的invalidated事件和changed事件。没有失效或改变
        // property01和property02,不会触发Property的invalidated和changed事件
        properties.add(property01);
//        properties.add(property02);
        
        // 修改Property数值,触发invalidated事件和changed事件。不会触发Property所在的ObservableList的
        // invalidated事件和changed事件
        System.out.println("----------------Property test------------------------");
        properties.get(0).set(10);
        System.out.println("----------------Property test------------------------\n");

        // 删除ObservableList中元素,触发ObservableList的invali事件(如果注册changed事件,同时也会触发)
        System.out.println("============ObservableList test======================");
        properties.remove(0);
        System.out.println("============ObservableList test==================\n");
    }
    
    /**
     * @class   ListInvalidationTest01
     * @date    2023-06-12 19:00
     * @author  qiao wei
     * @version 1.0
     * @brief   Property invalidated event.
     * @param   
     * @return  
     * @throws
     */
    public static void invalidatedForProperty(Observable observable) {
        System.out.println("Property invalidated event   &&&&&&&&&&&&&&&&&&&&&&");
        System.out.println(observable.toString());
        System.out.println("Property invalidated event   &&&&&&&&&&&&&&&&&&&&&&\n");
    }
    
    /**********************************************************************************************
     * @class   ListInvalidationTest01
     * @date    2023-02-01 14:49
     * @author  qiao wei
     * @version 1.0
     * @brief   Property changed event
     * @param   
     * @return  
     * @throws
     *********************************************************************************************/
    public static void changedForProperty(ObservableValue<? extends Number> observable,
                                          Number oldValue,
                                          Number newValue) {
        System.out.println("&&&&&&&&&&&&&&&&&&&&&&   Property changed event");
        // Observable instance's value is the new value
        System.out.println("Property's value : " + observable.getValue().intValue());
        System.out.println("Number changed : ");
        System.out.println("Old = " + oldValue.toString() + ", New = " + newValue.toString());
        System.out.println("&&&&&&&&&&&&&&&&&&&&&&   Property changed event\n");
    }
    
    /**********************************************************************************************
     * @class   ListInvalidationTest01
     * @date    2023-01-31 18:11
     * @author  qiao wei
     * @version 1.0
     * @brief   ObservableList invalidated event
     * @param   
     * @return  
     * @throws
     *********************************************************************************************/
    public static void invalidated(Observable observable) {
        System.out.println("ObservableList invalidated event ----------------------------");
        System.out.println(observable.toString());
        System.out.println("ObservableList invalidated event ----------------------------\n");
    }
    
    /**********************************************************************************************
     * @class   ListInvalidationTest01
     * @date    2023-01-31 18:11
     * @author  qiao wei
     * @version 1.0
     * @brief   ObservableList onChanged event
     * @param   
     * @return  
     * @throws
     *********************************************************************************************/
    public static void onChanged(ListChangeListener.Change<? extends IntegerProperty> change) {
        System.out.println("-------------------------------ObservableList onChanged event");
        if (change.next()) {
            System.out.println("&&&" + change.toString());
        }
        System.out.println("-------------------------------ObservableList onChanged event\n");
    }
}

运行结果:

ObservableList invalidated event ----------------------------
[IntegerProperty [value: 22]]
ObservableList invalidated event ----------------------------

-------------------------------ObservableList onChanged event
&&&{ [IntegerProperty [value: 22]] added at 0 }
-------------------------------ObservableList onChanged event

----------------Property test------------------------
Property invalidated event   &&&&&&&&&&&&&&&&&&&&&&
IntegerProperty [value: 10]
Property invalidated event   &&&&&&&&&&&&&&&&&&&&&&

&&&&&&&&&&&&&&&&&&&&&&   Property changed event
Property's value : 10
Number changed : 
Old = 22, New = 10
&&&&&&&&&&&&&&&&&&&&&&   Property changed event

----------------Property test------------------------

============ObservableList test======================
ObservableList invalidated event ----------------------------
[]
ObservableList invalidated event ----------------------------

-------------------------------ObservableList onChanged event
&&&{ [IntegerProperty [value: 10]] removed at 0 }
-------------------------------ObservableList onChanged event

============ObservableList test==================


Process finished with exit code 0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/702129.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【算法与数据结构】剑指 Offer 05、LeetCode替换空格

文章目录 一、题目二、双指针法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、双指针法 思路分析&#xff1a;这道题使用双指针法就能不用额外的辅助空间。首先计算字符串中的空格数量&#xff0c;然后重设…

函数模板和类模板 知识点总结 C++程序设计与算法笔记总结(七) 北京大学 郭炜

函数模板 交换两个整型变量的值的Swap函数&#xff1a; void Swap(int & x,int & y) { int tmp x; x y; y tmp; } 交换两个double型变量的值的Swap函数: void Swap(double & x,double & y) { double tmp x; x y; y tmp; }用函数模板解决&#xff1a; …

MAYA动力学曲线带动骨骼

例子 2 自由下落了 对比测试 尖端 太麻烦&#xff0c;使用风 nucleus1.windDirectionZ10*sin(time) 把球合成一个 删除一个解算器&#xff0c;就不动了

Redis 性能管理/优化 双一致性问题 缓存雪崩/击穿/穿透

---------------------- Redis 性能管理 ---------------------------------------- ----- 查看Redis内存使用 ----- info memoryredis-cli -a abc123 info memory ----- 内存碎片率 ----- used_memory_rss&#xff1a;是Redis向操作系统申请的内存。used_memory&#xff1a;是…

从有序顺序表中删除所有其值重复的元素(用不同的负数代替),使所有元素的值均不同。

题目要求&#xff1a;从有序顺序表中删除所有其值重复的元素&#xff08;用不同的负数代替&#xff09;&#xff0c;使所有元素的值均不同。 0&#xff1a;有序顺序表 1&#xff1a;删除所有其值重复的元素 2&#xff1a;用不同的负数代替 3&#xff1a;顺序表中所有元素的值均…

Maven中依赖使用范围

IDEA中help中show Log in Explorer可以查看idea日志 依赖使用范围 构建包含的流程&#xff1a;编译 &#xff0c;测试 &#xff0c;运行 &#xff0c;打包 &#xff0c;安装 &#xff0c;部署 comile test package install deploy 使用标签 1&#xff1a;compile 缺省值 伴随者…

OpenStack(T版)——块存储(Cinder)服务介绍与安装

文章目录 OpenStack(T版)——块存储(Cinder)服务介绍与安装安装和配置(controller)准备(1)创建数据库(2)加载admin user的环境变量(3)创建Identity服务凭据(4)创建Cinder 块存储服务组件的API endpoint 安装和配置Cinder块存储服务组件(1)安装软件包(2)编辑/etc/cinder/cinder.…

第七章:使用FileZilla搭建FTP服务器详解

目录 一、软件下载 二、服务器安装与配置 三、使用客户端 一、软件下载 到官方网站下载 FileZilla 的服务端和客户端程序 &#xff1a; FileZilla - The free FTP solution 二、服务器安装与配置 1 安装 安装的过程非常简单&#xff0c;直接下一步就可以了&#xff0c;需要…

【热部署】springboot-devtools

目录 pom idea配置 1 2 2021往后的idea版本 之前的idea版本 3 说明 注意 pom <!-- <!&ndash; 热部署 &ndash;>--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devt…

前端开发中的ajax请求、axios封装

目录 浏览器http请求 同步 js标签跨域、url 异步ajax、websock协议 ajax是异步的技术术语&#xff0c;最早的api是xhr&#xff08;XMLHttpRequest&#xff09; fetch es6 api axios 封装axios src/utils/request.ts src/utils/func.ts SSO&#xff08;Single Sign-On…

基于JAVA SpringBoot和Vue UniApp外卖订餐小程序

随着社会的发展和进步&#xff0c;网络信息技术的迅速发展已经渗透到我们生活的各个角落&#xff0c;传统餐饮业也受到了很大的影响&#xff0c;大部分传统中餐馆都开门&#xff0c;最多只能通过一个电话预约。但是在中国春节长假期间&#xff0c;餐厅不能接待这么多顾客。因此…

zabbix6.0LTS 配置proxy分布式监控

一、环境介绍 角色IP备注zabbix_server192.168.1.17zabbix_proxy192.168.1.14rpm包方式安装zabbix_agent192.168.1.18源码包安装 二、部署zabbix_proxy数据库 zabbix_proxy必须要安装一个数据库.zabbix官网推荐使用mariadb数据库&#xff0c;本人尝试过使用mysql8.0。由于内…

一步一步学OAK之十二:DepthAI API中Nodes各节点特性总结

目录 ColorCamera节点EdgeDetector节点FeatureTracker 节点ImageManip节点IMU 节点MobileNetDetectionNetwork节点MobileNetSpatialDetectionNetwork节点MonoCamera节点NeuralNetwork节点ObjectTracker节点Script节点SpatialLocationCalculator节点SPIIn节点SPIOut节点StereoDe…

2023年华中杯数学建模A题新型镇静药物临床实验疗效分析与预测解题全过程文档及程序

2023年华中杯数学建模 A题 新型镇静药物临床实验疗效分析与预测 原题再现 临床研究是新药物研究中的关键环节。本题拟围绕一种新型镇静药物的临床实验数据分析展开。 尝试根据附件中提供的数据和相关材料&#xff0c;研究以下问题&#xff1a;   1. 关于术中、术后 24h 不良…

React V6实现v-if、v-show、v-html

功能背景 在vue中使用v-if、v-show、v-html这些命令得心应手&#xff0c;那么react是否也存在这样的命令呢&#xff1f;似乎是没有的&#xff0c;需要自己实现&#xff0c;也就是用原生的写法直接控制dom。 实际效果 代码实现 const [dialogVisible, setDialogVisible] useSt…

Linux学习之守护进程

守护进程是daemon&#xff08;也称作精灵进程&#xff09;&#xff0c;守护进程不需要终端就可以启动起来&#xff0c;另外它的日志会打印到一些特殊文件中&#xff0c;并且占用的目录是根目录&#xff0c;避免占用其他目录&#xff0c;避免想要卸载其他目录时&#xff0c;报无…

taobao/天猫整店采集(店铺宝贝列表接口)

对于做竟店分析来说&#xff0c;首先要知道店铺有哪些商品&#xff0c;店铺宝贝列表则提供了这样的入口&#xff0c;可以查看该店铺的所有宝贝&#xff0c;也可以通过关键词全局搜索来获取店铺宝贝&#xff0c;但搜索会夹带这很多推荐的结果在里面&#xff0c;会比较混乱。 淘宝…

软件破解专题01

玩脱壳&#xff1f; 破解的功能&#xff1a;可以把收费软件免费使用 推荐论坛&#xff1a;pyg论坛》www.chinapyg.com 逆向&#xff1a;团队合作&#xff0c;有条件可以参加ctf大赛&#xff0c;这个应该是进步最快的途径 一个很强的开源项目&#xff1a;de4dot 作者…

Qt加载百度地图实现地图浏览(一)

一、功能介绍 在使用Qt中的QWebEngineView实现加载百度地图,并提供地图浏览功能。用户可以在Qt应用程序中显示百度地图,并使用常见的地图操作(如缩放、平移等)进行交互。 QWebEngine用于在Qt应用程序中嵌入Web内容。提供了对现代Web技术(如HTML5、CSS3、JavaScript等)的…

【Java高级编程】网络编程

网络编程 1、InetAddress类的使用1.1、实现网络通信需要解决的两个问题1.2、网络通信的两个要素1.3、通信要素一&#xff1a;IP和端口号1.4、通信要素二&#xff1a;网络通信协议1.5、TCP和UDP的区别1.6、TCP三次握手和四次挥手 2、TCP网络编程3、UDP网络编程4、URL编程4.1、UR…