JavaFX:Observable和ObservableValue的事件处理(invalidated和changed),Observable***集合处理Invalidated事件和***Change

104 篇文章 5 订阅

 20231224更新:增加Observable***集合处理监听事件。

一、JavaFX提供了Observable接口和ObservableValue接口, 处理invalidated(数据失效)和changed(数据更新)事件。

示例一:

自定义类继承InvalidationListener接口,当数据失效时,触发该接口的invalidated事件。

Book数据类,其中的变量分别是StringProperty类型和DoubleProperty类型。分别注册InvalidationListener接口的实现ObservableEvent类。

package javafx8.ch03.observablelist;


import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

/**
 * @copyright 2003-2023
 * @package   javafx8.ch03.observablelist
 * @file      Book.java
 * @date      2023-12-22 16:13
 * @author    qiao wei
 * @version   1.0
 * @brief     
 * @history
 */
public class Book {
    
    public Book(String isbn, String bookTitle, double price) {
        isbnProperty = new SimpleStringProperty(this, "ISBN", isbn);
        bookTitleProperty = new SimpleStringProperty(this, "Book", bookTitle);
        priceProperty = new SimpleDoubleProperty(this, "Price",  price);
        
        // 变量属性注册Invalidated事件和Changed事件。
        invalidationEvent = new InvalidationEvent();
        isbnProperty.addListener(invalidationEvent::invalidated);
        bookTitleProperty.addListener(invalidationEvent::invalidated);
        priceProperty.addListener(invalidationEvent::invalidated);
        changeEvent = new ChangeEvent();
        isbnProperty.addListener(changeEvent::changed);
        bookTitleProperty.addListener(changeEvent::changed);
        priceProperty.addListener(changeEvent::changed);
    }
    
    public String getIsbn() {
        return isbnProperty.get();
    }
    
    public void setIsbn(String isbn) {
        isbnProperty.set(isbn);
    }
    
    public String getBookTitle() {
        return bookTitleProperty.get();
    }
    
    public void setBookTitle(String bookTitle) {
        bookTitleProperty.set(bookTitle);
    }
    
    public double getPrice() {
        return priceProperty.get();
    }
    
    public void setPrice(double price) {
        priceProperty.set(price);
    }
    
    public static final String ISBN = "ISBN";
    
    public static final String BOOK = "Book";
    
    public static final String PRICE = "Price";
    
    private StringProperty isbnProperty;
    
    private StringProperty bookTitleProperty;
    
    private DoubleProperty priceProperty;
    
    private InvalidationEvent invalidationEvent;
    
    private ChangeEvent changeEvent;
}

InvalidationEvent类,继承InvalidationListener接口:

package javafx8.ch03.observablelist;


import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.StringProperty;


/**
 * @copyright 2003-2023
 * @package   javafx8.ch03.observablelist
 * @file      InvalidationEvent.java
 * @date      2023-12-22 16:22
 * @author    qiao wei
 * @version   1.0
 * @brief     
 * @history
 */
public class InvalidationEvent implements InvalidationListener {
    
    public InvalidationEvent() {}

    @Override
    public void invalidated(Observable observable) {
        System.out.println("········································调用Invalidated方法");
        String name = null;
        StringProperty stringProperty = null;
        DoubleProperty doubleProperty = null;
        if (observable instanceof StringProperty) {
            stringProperty = (StringProperty) observable;
            name = stringProperty.getName();
        } else if (observable instanceof DoubleProperty) {
            doubleProperty = (DoubleProperty) observable;
            name = doubleProperty.getName();
        }
        
        switch (name) {
            case Book.ISBN:
                System.out.println(name + ": " + stringProperty.get());
                break;
                
            case Book.BOOK:
                System.out.println(name + ": " + stringProperty.get());
                break;
                
            case Book.PRICE:
                System.out.println(name + ": " + doubleProperty.get());
                break;
                
            default:
                break;
        }

        System.out.println("········································调用Invalidated方法");
        System.out.println();
    }
}

ChangeEvent类,继承ChangeListener<T>接口:

package javafx8.ch03.observablelist;


import javafx.beans.property.DoubleProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;


/**
 * @copyright 2003-2023
 * @package   javafx8.ch03.observablelist
 * @file      ChangeEvent.java
 * @date      2023-12-23 17:23
 * @author    qiao wei
 * @version   1.0
 * @brief     
 * @history
 */
public class ChangeEvent implements ChangeListener {
    
    public ChangeEvent() {}

    @Override
    public void changed(ObservableValue observableValue, Object oldValue, Object newValue) {
        System.out.println("调用Changed方法+++++++++++++++++++++++++++++++++++");
        String name = null;
        StringProperty stringProperty = null;
        DoubleProperty doubleProperty = null;
        if (observableValue instanceof StringProperty) {
            stringProperty = (StringProperty) observableValue; 
            name = stringProperty.getName();
        } else if (observableValue instanceof DoubleProperty) {
            doubleProperty = (DoubleProperty) observableValue;
            name = doubleProperty.getName();
        }

        switch (name) {
            case Book.ISBN:
                System.out.println(name + ": " + stringProperty.get());
                break;

            case Book.BOOK:
                System.out.println(name + ": " + stringProperty.get());
                break;

            case Book.PRICE:
                System.out.println(name + ": " + doubleProperty.get());
                break;

            default:
                break;
        }

        System.out.println("调用Changed方法+++++++++++++++++++++++++++++++++++");
        System.out.println();
    }
}

测试代码:

package javafx8.ch03.observablelist;


/**
 * @copyright 2003-2023
 * @package   javafx8.ch03.observablelist
 * @file      BookTest.java
 * @date      2023-12-22 16:35
 * @author    qiao wei
 * @version   1.0
 * @brief     
 * @history
 */
public class BookTest {

    public static void main(String[] args) {
        test01();
    }
    
    private static void test01() {
        Book book01 = new Book("123", "Test01", 22.55D);
        book01.setIsbn("222---");
        
        book01.setPrice(22.3d);
    }
}

运行结果:

········································调用Invalidated方法
ISBN: 222---

调用Changed方法+++++++++++++++++++++++++++++++++++
ISBN: 222---

········································调用Invalidated方法
Price: 22.3

调用Changed方法+++++++++++++++++++++++++++++++++++
Price: 22.3

程序更新String类型、double类型数据,也许是应为Observable接口是ObservableValue接口的父类,先后依次触发invalidated事件,changed事件。

二、Observable***集合处理Invalidated事件和***ChangeListener.Change事件(因为有List,Map,Set三种集合)

集合的Invalidated事件是因为集合继承了Observable接口,但是没有继承ObservableValue接口,所以没有属性Property中定义的changed事件。但是集合自身定义了***ChangeListener.Change,类似changed事件。绑定集合的事件类如下:

ListInvalidatedEvent类:

package javafx8.ch03.observablelist;


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


/**
 * @copyright 2003-2023
 * @package   javafx8.ch03.observablelist
 * @file      ListInvalidatedEvent.java
 * @date      2023-12-23 19:07
 * @author    qiao wei
 * @version   1.0
 * @brief     
 * @history
 */
public class ListInvalidatedEvent implements InvalidationListener {
    
    /**
     * @class   ListInvalidatedEvent
     * @date    2023-12-23 19:41
     * @author  qiao wei
     * @version 1.0
     * @brief   
     * @param   
     * @return  
     * @throws
     */
    @Override
    public void invalidated(Observable observable) {
        System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&调用集合Invalidated方法");
        System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&调用集合Invalidated方法");
        
        if (observable instanceof ObservableList) {
            ObservableList<Book> books = (ObservableList<Book>) observable;
            System.out.println("打印集合中所有元素信息:");
            for (Book book: books) {
                System.out.println(book.getBookTitle() + ", " +
                    book.getIsbn() + ", " +
                    book.getPrice()
                );
            }
            
            System.out.println("集合中元素个数:" + books.size());
        }

        System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&调用集合Invalidated方法");
        System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&调用集合Invalidated方法");
        System.out.println();
    }
}

ListChangeEvent类:

package javafx8.ch03.observablelist;


import javafx.collections.ListChangeListener;


/**
 * @copyright 2003-2023
 * @package   javafx8.ch03.observablelist
 * @file      ListChangeEvent.java
 * @date      2023-12-24 11:18
 * @author    qiao wei
 * @version   1.0
 * @brief     
 * @history
 */
public class ListChangeEvent implements ListChangeListener {
    
    public ListChangeEvent() {}

    @Override
    public void onChanged(Change change) {
        System.out.println("】】】】】】】】】】】】】】】】】调用集合onChanged方法");
    }
}

测试类BookTest代码,测试在test02函数中。

package javafx8.ch03.observablelist;


import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import javafx.beans.InvalidationListener;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;

/**
 * @copyright 2003-2023
 * @package   javafx8.ch03.observablelist
 * @file      BookTest.java
 * @date      2023-12-22 16:35
 * @author    qiao wei
 * @version   1.0
 * @brief     
 * @history
 */
public class BookTest {

    public static void main(String[] args) {
//        test01();
        test02();
    }
    
    private static void test01() {
        Book book01 = new Book("123", "Test01", 22.55D);
        book01.setIsbn("987654321");
        
        book01.setPrice(22.3d);
    }
    
    /**
     * @class   BookTest
     * @date    2023-12-24 10:24
     * @author  qiao wei
     * @version 1.0
     * @brief   将数据插入ObservableList实例books,给books注册Invalidated事件,并测试验证Invalidated事件。
     * @param   
     * @return  
     * @throws
     */
    private static void test02() {
        Book book01 = new Book("123", "Test01", 22.55D);
        Book book02 = new Book("ABC", "Test02", 3333.55D);
        Book book03 = new Book("~!@", "Test02", 5555.5D);

        ObservableList<Book> books = FXCollections.observableArrayList();
        InvalidationListener listInvalidatedEvent = new ListInvalidatedEvent();
        ListChangeListener listChangeListener = new ListChangeEvent();
        books.addListener(listInvalidatedEvent::invalidated);
        books.addListener(listChangeListener::onChanged);
        books.addAll(book01, book02, book03);
//        books.addListener(listInvalidatedEvent::invalidated);
//        books.addListener(listChangeListener::onChanged);
        
        book01.setPrice(22.3d);
        books.remove(1);
    }
}

测试结果:

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&调用集合Invalidated方法
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&调用集合Invalidated方法
打印集合中所有元素信息:
Test01, 123, 22.55
Test02, ABC, 3333.55
Test02, ~!@, 5555.5
集合中元素个数:3
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&调用集合Invalidated方法
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&调用集合Invalidated方法

】】】】】】】】】】】】】】】】】调用集合onChanged方法
········································调用Invalidated方法
Price: 22.3
········································调用Invalidated方法

调用Changed方法+++++++++++++++++++++++++++++++++++
Price: 22.3
调用Changed方法+++++++++++++++++++++++++++++++++++

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&调用集合Invalidated方法
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&调用集合Invalidated方法
打印集合中所有元素信息:
Test01, 123, 22.3
Test02, ~!@, 5555.5
集合中元素个数:2
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&调用集合Invalidated方法
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&调用集合Invalidated方法

】】】】】】】】】】】】】】】】】调用集合onChanged方法

Process finished with exit code 0

注意,如果两个事件注册在添加元素之后,则集合添加元素的导致集合失效(Invalidated)、变化(onChanged)事件不会触发。

如果只是改变集合中元素数据,则只会调用元素绑定的事件,而不会调用集合绑定的事件。

反过来,只改变集合中元素,但是元素本身数据不改变,则只调用集合绑定的事件,不会调用元素自身绑定的事件。

注意:

  • 两个测试示例中,集合绑定的事件都在集合添加元素之后,所以集合添加元素时没有触发事件(因为没有绑定事件)。
  • 同级别的事件如果2个事件都绑定了,一般都是Invalidated先触发,changed/onChanged事件后触发。

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值