JavaFX可观察列表---一个完整的观察ObservableList变化的例子

首先需要声明一个要观察的对象,本例子中要观察的对象是Person,Person包含名和姓两个属性,然后为该类编写setter和getter。

package com.jdojo.collections;

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

public class Person implements Comparable<Person> {
    private StringProperty firstName = new SimpleStringProperty();
    private StringProperty lastName = new SimpleStringProperty();

    public Person() {
        this.setFirstName("Unknown");
        this.setLastName("Unknown");
    }

    public Person(String firstName, String lastName) {
        this.setFirstName(firstName);
        this.setLastName(lastName);
    }

    public final String getFirstName() {
        return firstName.get();
    }

    public final void setFirstName(String newFirstName) {
        firstName.set(newFirstName);
    }

    public StringProperty firstNameProperty() {
        return firstName;
    }

    public final String getLastName() {
        return lastName.get();
    }

    public final void setLastName(String newLastName) {
        lastName.set(newLastName);
    }

    public StringProperty lastNameProperty() {
        return lastName;
    }

    @Override
    public int compareTo(Person p) {
        // Assume that the first and last names are always not null
        int diff = this.getFirstName().compareTo(p.getFirstName());
        if (diff == 0) {
            diff = this.getLastName().compareTo(p.getLastName());
        }

        return diff;
    }

    @Override
    public String toString() {
        return getFirstName() + " " + getLastName();
    }
}

然后编写更改监听器类,它实现ListChangeListener接口的onChanged()方法来处理Person对象的ObservableList的所有类型的更改通知。

// PersonListChangeListener.java
package com.jdojo.collections;

import java.util.List;
import javafx.collections.ListChangeListener;

public class PersonListChangeListener implements ListChangeListener<Person> {
    @Override
    public void onChanged(ListChangeListener.Change<? extends Person> change) {
        while (change.next()) {
            if (change.wasPermutated()) {   //被重新排列
                handlePermutated(change);
            }
            else if (change.wasUpdated()) {    //被更新
                handleUpdated(change);
            }
            else if (change.wasReplaced()) {    //被替换
                handleReplaced(change);
            }
            else {
                if (change.wasRemoved()) {
                    handleRemoved(change);
                }
                else if (change.wasAdded()) {
                    handleAdded(change);
                }
            }
        }
    }

    public void handlePermutated(ListChangeListener.Change<? extends Person> change) {
        System.out.println("Change Type: Permutated");
        System.out.println("Permutated Range: " + getRangeText(change));
        int start = change.getFrom();
        int end = change.getTo();
        for(int oldIndex = start; oldIndex < end; oldIndex++) {
            int newIndex = change.getPermutation(oldIndex);
            System.out.println("index[" + oldIndex + "] moved to " +
                    "index[" + newIndex + "]");
        }
    }

    public void handleUpdated(ListChangeListener.Change<? extends Person> change) {
        System.out.println("Change Type: Updated");
        System.out.println("Updated Range : " + getRangeText(change));
        System.out.println("Updated elements are: " +
                change.getList().subList(change.getFrom(), change.getTo()));
    }

    public void handleReplaced(ListChangeListener.Change<? extends Person> change) {
        System.out.println("Change Type: Replaced");

        // A "replace" is the same as a “remove” followed with an "add"
        handleRemoved(change);
        handleAdded(change);
    }

    public void handleRemoved(ListChangeListener.Change<? extends Person> change) {
        System.out.println("Change Type: Removed");

        int removedSize = change.getRemovedSize();
        List<? extends Person> subList = change.getRemoved();

        System.out.println("Removed Size: " + removedSize);
        System.out.println("Removed Range: " + getRangeText(change));
        System.out.println("Removed List: " + subList);
    }

    public void handleAdded(ListChangeListener.Change<? extends Person> change) {
        System.out.println("Change Type: Added");

        int addedSize = change.getAddedSize();
        List<? extends Person> subList = change.getAddedSubList();

        System.out.println("Added Size: " + addedSize);
        System.out.println("Added Range: " + getRangeText(change));
        System.out.println("Added List: " + subList);
    }

    public String getRangeText(ListChangeListener.Change<? extends Person> change) {
        return "[" + change.getFrom() + ", " + change.getTo() + "]";
    }
}

然后创建一个测试类,类中创建了一个带有提取器的ObservableList,提取器返回Person对象的firstName和lastName属性数组。这意味着当这些属性之一发生更改时,作为列表元素的Person对象被视为已更新,并且将向所有更改侦听器发送更新通知。然后向列表中添加一个更改监听器。最后,对列表进行几种类型的更改来触发更改通知,更改通知的详细信息打印在标准输出中。

package com.jdojo.collections;

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

public class ListChangeTest {
    public static void main(String[] args) {
        Callback<Person, Observable[]> cb =
                (Person p) -> new Observable[] {
                        p.firstNameProperty(),
                        p.lastNameProperty()
                };

        // Create a list
        ObservableList<Person> list = FXCollections.observableArrayList(cb);

        // Add a change listener to the list
        list.addListener(new PersonListChangeListener());

        Person p1 = new Person("Li", "Na");
        System.out.println("Before adding " + p1 + ": " + list);
        list.add(p1);
        System.out.println("After adding " + p1 + ": " + list) ;

        Person p2 = new Person("Vivi", "Gin");
        Person p3 = new Person("Li", "He");
        System.out.println("\nBefore adding " + p2 + " and " + p3 + ": " + list);
        list.addAll(p2, p3);
        System.out.println("After adding " + p2 + " and " + p3 + ": " + list);

        System.out.println("\nBefore sorting the list:" + list);
        FXCollections.sort(list);
        System.out.println("After sorting the list:" + list);

        System.out.println("\nBefore updating " + p1 + ": " + list);
        p1.setLastName("Smith");
        System.out.println("After updating " + p1 + ": " + list);

        Person p = list.get(0);
        Person p4 = new Person("Simon", "Ng");
        System.out.println("\nBefore replacing " + p +
                " with " + p4 + ": " + list);
        list.set(0, p4);
        System.out.println("After replacing " + p + " with " + p4 + ": " + list);

        System.out.println("\nBefore setAll(): " + list);
        Person p5 = new Person("Lia", "Li");
        Person p6 = new Person("Liz", "Na");
        Person p7 = new Person("Li", "Ho");
        list.setAll(p5, p6, p7);
        System.out.println("After setAll(): " + list);

        System.out.println("\nBefore removeAll(): " + list);
        list.removeAll(p5, p7); // Leave p6 in the list
        System.out.println("After removeAll(): " + list);

        Person p8 = new Person();
        list.add(p8);
    }
}

输出结果:

Before adding Li Na: []
Change Type: Added
Added Size: 1
Added Range: [0, 1]
Added List: [Li Na]
After adding Li Na: [Li Na]

Before adding Vivi Gin and Li He: [Li Na]
Change Type: Added
Added Size: 2
Added Range: [1, 3]
Added List: [Vivi Gin, Li He]
After adding Vivi Gin and Li He: [Li Na, Vivi Gin, Li He]

Before sorting the list:[Li Na, Vivi Gin, Li He]
Change Type: Permutated
Permutated Range: [0, 3]
index[0] moved to index[1]
index[1] moved to index[2]
index[2] moved to index[0]
After sorting the list:[Li He, Li Na, Vivi Gin]

Before updating Li Na: [Li He, Li Na, Vivi Gin]
Change Type: Updated
Updated Range : [1, 2]
Updated elements are: [Li Smith]
After updating Li Smith: [Li He, Li Smith, Vivi Gin]

Before replacing Li He with Simon Ng: [Li He, Li Smith, Vivi Gin]
Change Type: Replaced
Change Type: Removed
Removed Size: 1
Removed Range: [0, 1]
Removed List: [Li He]
Change Type: Added
Added Size: 1
Added Range: [0, 1]
Added List: [Simon Ng]
After replacing Li He with Simon Ng: [Simon Ng, Li Smith, Vivi Gin]

Before setAll(): [Simon Ng, Li Smith, Vivi Gin]
Change Type: Replaced
Change Type: Removed
Removed Size: 3
Removed Range: [0, 3]
Removed List: [Simon Ng, Li Smith, Vivi Gin]
Change Type: Added
Added Size: 3
Added Range: [0, 3]
Added List: [Lia Li, Liz Na, Li Ho]
After setAll(): [Lia Li, Liz Na, Li Ho]

Before removeAll(): [Lia Li, Liz Na, Li Ho]
Change Type: Removed
Removed Size: 1
Removed Range: [0, 0]
Removed List: [Lia Li]
Change Type: Removed
Removed Size: 1
Removed Range: [1, 1]
Removed List: [Li Ho]
After removeAll(): [Liz Na]

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值