JavaBean添加绑定/约束监听器(Property/VetoableChangeSupport)

java为我们提供了两个类,分别提供对bean的绑定属性,以及约束属性的侦听功能

PropertyChangeSupport/VetoableChangeSupport

 

其中,绑定属性只能监听到属性的更改,却不能中断所做的操作,而约束属性可以通过抛出PropertyVetoException异常的方式阻止属性的更改

首先,定义一个javabean,在成员属性中添加PropertyChangeSupport 和VetoableChangeSupport ,并在构造方法中对其初始化

  因为要监听到属性的更改,所以应该在set方法中添加触发监听器的代码

 1 package javaBeanDemo;
 2 
 3 import java.beans.PropertyChangeListener;
 4 import java.beans.PropertyChangeSupport;
 5 import java.beans.PropertyVetoException;
 6 import java.beans.VetoableChangeListener;
 7 import java.beans.VetoableChangeSupport;
 8 import java.io.Serializable;
 9 
10 public class ProBean  implements Serializable{
11     /**
12      * 
13      */
14     private static final long serialVersionUID = 1L;
15     private String name;
16     private PropertyChangeSupport pcs;
17     private VetoableChangeSupport vcs;
18 
19     public ProBean(String name) {
20         this.name = name;
21         pcs=new PropertyChangeSupport(this);
22         vcs=new VetoableChangeSupport(this);
23     }
24 
25     public ProBean(){
26         pcs=new PropertyChangeSupport(this);
27         vcs=new VetoableChangeSupport(this);
28     }
29 
30     public String getName() {
31         return name;
32     }
33     
34     //值被改变后,触发监听器
35     public void setName(String name) throws PropertyVetoException {
36         String oldValue=this.getName();
37         String newValue=name;
38 //        System.out.println("######SetName######");
39         vcs.fireVetoableChange("name", oldValue, newValue);
40         this.name = name;
41         pcs.firePropertyChange("name", oldValue, newValue);
42     }
43     //监听器的添加/删除方法
44     public void addPropertyChangeListener(PropertyChangeListener Listener ){
45         pcs.addPropertyChangeListener(Listener);
46     }
47     public void addVetoableChangeListener(VetoableChangeListener Listener){
48         vcs.addVetoableChangeListener(Listener);
49     }
50     public void removePropertyChangeListener(PropertyChangeListener Listener ){
51         pcs.removePropertyChangeListener(Listener);
52     }
53     public void removeVetoableChangeListener(VetoableChangeListener Listener){
54         vcs.removeVetoableChangeListener(Listener);
55     }
56     
57     
58 
59 }


注意,因为VetoableChangeListener拥有阻止更改的权利,所以,应该在属性值被更改前触发

vcs.fireVetoableChange("name", oldValue, newValue);

而PropertyChangeListener在属性值被更改后触发

pcs.firePropertyChange("name", oldValue, newValue);

传递的三个参数分别为:要更改的属性名,旧的值,和将要更改的值

这三个参数会被封装成一个PropertyChangeEvent对象传递给我们的listener对象(前提是该listener已经被添加为该bean的监听器)

最后,再bean中添加添加监听器和移出监听器的方法:直接调用*ChangeSupport方法中的romove和add方法即可

然后,在写用于监听bean的属性变化的监听器。由于该bean定义了两个属性(绑定/约束),所以,该监听器应该实现两个接口: implements PropertyChangeListener,VetoableChangeListener

分别实现接口中的vetoableChangepropertyChange方法

package Listener;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;

public class listener implements PropertyChangeListener,VetoableChangeListener {

    @Override
    public void vetoableChange(PropertyChangeEvent evt)
            throws PropertyVetoException {
        // TODO Auto-generated method stub
        if(evt.getNewValue().equals("frank"))
            throw new PropertyVetoException("新值不能是frank", evt);
        
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        // TODO Auto-generated method stub
        System.out.println("#######proChange#######");
        System.out.println("新值:"+evt.getNewValue());
        System.out.println("旧值"+evt.getOldValue());
        
    }

}

在vetoableChange方法中,我们定义如图更改的值为frank,则抛出异常,阻止属性的更改

而propertyChange没有更改的权利,只是把新值与旧值打印到控制台

最后写测试类:

package test;

import java.beans.PropertyVetoException;

import Listener.listener;
import javaBeanDemo.ProBean;

public class TestMain {

    public static void main(String[] args)   {
        // TODO Auto-generated method stub
        ProBean pb=new ProBean("lee");
        listener lis=new listener();
        pb.addPropertyChangeListener(lis );
        pb.addVetoableChangeListener(lis);
        try {
            pb.setName("fred");
            pb.setName("frank");
            
        } catch (PropertyVetoException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    


    }

}
原文地址:https://www.cnblogs.com/frankM/p/4448591.html