栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

javafx应用观察者模式的属性类分析并用kotlin实现

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

javafx应用观察者模式的属性类分析并用kotlin实现

1.观察者模式

当我们期望目标值发生变化后其他相关依赖对象可以得到通知并更新,就可以用观察者模式。观察者模式最简单的结构就是一个被观察者和一个实现了响应方法的观察列表。

被观察者:

public class MyObservable {
    private int i=0;
    private List observableList=new ArrayList();
    public void set(int newValue){
        i=newValue;
        for (BeObservable observable: observableList) {
            observable.change(i);
        }
    }
}

观察者:

​
class BeObservable{
    private String name;
    public BeObservable(String name) {
        this.name = name;
    }
    public void change(int newValue){
        System.out.println(name+"得到了通知,最新值是"+newValue);
    }
}

​

主函数:

  public static void main(String[] args) {
        MyObservable myObservable = new MyObservable();
        myObservable.observableList.add(new BeObservable("张三"));
        myObservable.observableList.add(new BeObservable("李四"));
        myObservable.observableList.add(new BeObservable("王五"));
        myObservable.set(1);
    }

结果:

这样就实现了当一个目标值改变时所有观察者都会得到通知。

2.JavaFx的Simple类

javafx有一些包装的属性类如SimpleIntegerProperty等,这个类可以加监听器当其值发生变化时自动调用监听方法,很实用。

原理就是观察者模式,点开SimpleIntegerProperty的源码分析,肯定就是在set的时候调用了响应方法:

没有set方法,到父类中找:

点set方法:

  @Override
    public void set(int newValue) {
        if (isBound()) {
            throw new java.lang.RuntimeException((getBean() != null && getName() != null ?
                    getBean().getClass().getSimpleName() + "." + getName() + " : ": "") + "A bound value cannot be set.");
        }
        if (value != newValue) {
            value = newValue;
            markInvalid();
        }
    }

所以是调用了markInvalid()方法来通知观察列表,顺着markInvalid()一路点下去,直到点进ExpressionHelper的抽象方法。

在其子类中找到重写后的方法:

    @Override
        protected void fireValueChangedEvent() {
            final T oldValue = currentValue;
            currentValue = observable.getValue();
            final boolean changed = (currentValue == null)? (oldValue != null) : !currentValue.equals(oldValue);
            if (changed) {
                try {
                    listener.changed(observable, oldValue, currentValue);
                } catch (Exception e) {
                    Thread.currentThread().getUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), e);
                }
            }
        }

这里的listener.changed(observable, oldValue, currentValue)就是开始分析的观察者模式的响应方法。

3.Kotlin实现简单的监听类

常规javafx的监听实现方法:

SimpleIntegerProperty simpleIntegerProperty = new SimpleIntegerProperty(1); simpleIntegerProperty.addListener((observable, oldValue, newValue) -> { System.out.println("发生了改变"); });

javafx的监听需要重写ChangeListener接口中的change方法,其实写监听器时只是需要change函数,但是java的函数没有类型,所以通过实现接口方法来传递函数。但是kotlin的函数有类型,所以我们用kotlin的函数类型来写一个简单的监听类,当我们改变该类的值时会调用监听方法。

class HigherFunctions(var value: Int) {
    var oldValue:Int =0
    var changeAction:(oldValue:Int,newValue: Int)->Unit={oldValue,newValue-> println("旧值是$oldValue  新值是$newValue") }
    fun set(value: Int){
        oldValue=this.value
        this.value=value
        changeAction(oldValue,value)
    }
}

该类的changeAction属性就是一个函数类型属性,作用相当于java监听器中的change()方法,每当这个监听类的值改变的时候都会调用changeAction方法。我们可以对changeAction重新赋值来实现想要的响应方法:

fun main() {
    val mySimpleBean =HigherFunctions(0)
    mySimpleBean.changeAction={ _,newValue->
        println("自定义的方法打印新值$newValue")
    }
    mySimpleBean.set(5)
    mySimpleBean.set(7)
    mySimpleBean.set(2)
    mySimpleBean.set(1)
}

运行结果:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1036172.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号