JavaBeans 官方文档学习
提示,重点:JavaBeans的Property和 Events;PropertyEditor极其注册和查找机制。
从目前来看,JavaBeans 更像是源自GUI的需求。
使用NetBeans新建一个Java Application,然后新建一个jFrame form,右边会有组件面板,如下:

这些组件,本质上都是bean!所以可被复用、可被引用、可被通知!
将任意一个组件拖进去安置,例如Button(按钮)。如下:

在右下角会显示该组件的属性,如下:

如果是英文版的NetBeans,你就会发现这里的属性就是Properties。你在这里进行的所有设置,如设置图标、字体、边框、背景等等操作,本质上都是调用相应的SETTER!(在SETTER之前会先调用PropertyEditor)
官方文档有这么一句:
A bean is a Java class with method names that follow the JavaBeans guidelines. A bean builder tool uses introspection to examine the bean class. Based on this inspection, the bean builder tool can figure out the bean's properties, methods, and events. -- 原文
类似Netbeans这样的builder tool,会识别并展示所有的property name and type,以及其他,以方便设计者在设计时进行操作。
JavaBeans’ property 中有两个特殊的:bound property、constrained property,如下:
bound property,当其值发生改变时,会通知监听器!两个含义:
1,该bean类包含两个方法:
addPropertyChangeListener()andremovePropertyChangeListener()。2,当值发生改变时,该bean会发送
PropertyChangeEvent至注册过的监听器。
PropertyChangeEvent and PropertyChangeListener 都在 java.beans package中。
该包中还有一个类,PropertyChangeSupport,负责多数的bound properties工作。
代码示例如下:
import java.beans.*;
public class FaceBean {
private int mMouthWidth = 90;
private PropertyChangeSupport mPcs = new PropertyChangeSupport(this); // 这里
public int getMouthWidth() {
return mMouthWidth;
}
public void setMouthWidth(int mw) {
int oldMouthWidth = mMouthWidth; //
mMouthWidth = mw;
mPcs.firePropertyChange("mouthWidth", oldMouthWidth, mw); // 这里
}
// 这里
public void addPropertyChangeListener(PropertyChangeListener listener) {
mPcs.addPropertyChangeListener(listener);
}
// 这里
public void removePropertyChangeListener(PropertyChangeListener listener) {
mPcs.removePropertyChangeListener(listener);
}
}
constrained property,一种特殊的 bound property。bean会持续跟踪 a set of veto listeners。当constrained property 将要发生改变时,会先咨询监听器。任何一个veto listener都有机会否决这次改变,就是说,维持原值不变。
veto listeners独立于 property change listener。所幸, java.beans 包包含了一个 VetoableChangeSupport 类,可以极大的简化 constrained properties。
import java.beans.*;
public class FaceBean {
private int mMouthWidth = 90;
private PropertyChangeSupport mPcs = new PropertyChangeSupport(this);
private VetoableChangeSupport mVcs = new VetoableChangeSupport(this); // 这里
public int getMouthWidth() {
return mMouthWidth;
}
public void setMouthWidth(int mw) throws PropertyVetoException {
int oldMouthWidth = mMouthWidth;
mVcs.fireVetoableChange("mouthWidth", oldMouthWidth, mw); // 这里
mMouthWidth = mw;
mPcs.firePropertyChange("mouthWidth", oldMouthWidth, mw);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
mPcs.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
mPcs.removePropertyChangeListener(listener);
}
// 这里
public void addVetoableChangeListener(VetoableChangeListener listener) {
mVcs.addVetoableChangeListener(listener);
} // 这里
public void removeVetoableChangeListener(VetoableChangeListener listener) {
mVcs.removeVetoableChangeListener(listener);
}
}
JavaBeans’ method: A bean's methods are the things it can do. Any public method that is not part of a property definition is a bean method.
JavaBeans’ events: A bean class can fire off any type of event, including custom events.
和property一样,event也有自己的惯例:
public void add<Event>Listener(<Event>Listener a)
public void remove<Event>Listener(<Event>Listener a)
注意,listener必须是 java.util.EventListener 的子类。
类似NetBeans的builder tool可以识别 bean events。
使用BeanInfo
Beans,特别是图形组件,可能拥有大量的properties,难以快速的找到正确的properties进行编辑 -- 特别是对于新手来说。
BeanInfo可以改变bean在builder tool中的展示形式。Builder tool可以查询BeanInfo以找出哪些properties优先展示,哪些应该隐藏。
BeanInfo和bean的名字一样,但以 BeanInfo 结尾。例如,FaceBean与FaceBeanBeanInfo。
虽然可以手动创建BeanInfo,但是使用工具(如NetBeans)更简洁。
NetBeans中创建Bean的BeanInfo很简单,右键 - BeanInfo Editor… 即可。第一次会提示创建,同意即可。
默认进入源码编辑界面,记得切入设计界面。如下:


可以针对property进行选择,主要就是是否优先展示、是否隐藏、是否bound property、是否constrained property。
builder tool在发现一个bean类之后,会自动查找同路径下的BeanInfo,以决定如何展示bean。
JavaBeans入门很简单,但这货其实是很有深度的。现在来看点高级货,包括 如何持久化保存一个bean、如何为定制的类型提供定制的editor。
Bean Persistence (持久化)
想了下,这个也是源自GUI吧,总不能每次打开的界面都是最原始的界面。
The mechanism that makes persistence possible is called serialization. Object serialization means converting an object into a data stream and writing it to storage. Any applet, application, or tool that uses that bean can then "reconstitute" it by deserialization. The object is then restored to its original state.
囧了,居然是序列化和反序列化。
All beans must persist. To persist, your beans must support serialization by implementing either the
java.io.Serializable(in the API reference documentation) interface, or thejava.io.Externalizable(in the API reference documentation) interface. These interfaces offer you the choices of automatic serialization and customized serialization.
原来有两个接口,涨姿势了。
实现 Serializable的bean,可以自动序列化/反序列化,会自动忽略transient和static的字段。
The Java Object Serialization API automatically serializes most fields of a Serializable object to the storage stream. This includes primitive types, arrays,and strings. The API does not serialize or deserialize fields that are marked transient or static.
你可以控制你的bean的序列化level!三种途径:
- 自动序列化,实现Serializable接口即可。序列化整个对象,除了transient 和 static 字段。
- 定制序列化。将不想序列化的自动使用transient 或 static 修饰。— 囧。
- 定制文件格式,实现 Externalizable和其两个方法。Bean会被以那种文件格式写入。
默认序列化:Serializable接口,就是一个标记,告诉JVM希望进行默认序列化。有几个关键点需要知道:
类必须有一个针对父类无参构造的访问。
如果父类实现了Serializable接口,子类可以继承。
会忽略transient 和 static。 -- 各种重复啊
选择性序列化:writeObject 和 readObject
如果你的serializable class含有下面两个方法中的任意一个,默认的序列化就不会发生:
private void writeObject(java.io.ObjectOutputStream out) throws IOException;
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;
通过这两个方法,你可以控制如何序列化/反序列化。
Externalizable接口
完全控制bean的序列化/反序列化(例如,以一种特定文件格式进行读写)。
需要实现两个方法:writeExternal和readExternal。
实现类必须有一个无参构造。
Long Term Persistence 长期持久化
Long-term persistence is a model that enables beans to be saved in XML format.
居然只支持XML格式。
Encoder 和 Decoder
XMLEncoder类用于输出Serializable对象。例如:
XMLEncoder encoder = new XMLEncoder(
new BufferedOutputStream(
new FileOutputStream("Beanarchive.xml"))); encoder.writeObject(object);
encoder.close();
XMLDecoder类读取XMLEncoder创建的XML:
XMLDecoder decoder = new XMLDecoder(
new BufferedInputStream(
new FileInputStream("Beanarchive.xml"))); Object object = decoder.readObject();
decoder.close();
下面是SimpleBean的XML形式:
<?xml version="1.0" encoding="UTF-8" ?>
<java>
<object class="javax.swing.JFrame">
<void method="add">
<object class="java.awt.BorderLayout" field="CENTER"/>
<object class="SimpleBean"/>
</void>
<void property="defaultCloseOperation">
<object class="javax.swing.WindowConstants" field="DISPOSE_ON_CLOSE"/>
</void>
<void method="pack"/>
<void property="visible">
<boolean>true</boolean>
</void>
</object>
</java>
Bean Customization 定制
修改一个bean的appearance和behaviour,两种方式:
- 通过一个property editor。
- 通过customizer。 同property editor的区别是,customizer关联到bean,property editor关联到property。
PropertyEditor

这里的属性设值,都是调用了相应的PropertyEditor!-- 因为你输入的都是字符串啦。
例如,点击 toolTipText 后面的【…】,就会打开一个StringEditor window:

PropertyEditorSupport提供PropertyEditor接口的空实现,继承它,按需覆盖方法即可完成自己的PropertyEditor。
Property Editors 是如何关联到 Properties 的? (重点)
- 通过一个BeanInfo对象 显式的关联。
- 通过
java.beans.PropertyEditorManager.registerEditor方法 显式的注册。 - 名字查找。如果一个类没有显式的关联PropertyEditor,那 PropertyEditorManager 会按以下顺序搜索其editor:
同包路径下以类的名字开始,以’Editor’结束。
在classpath中搜索(以类的名字开始,以’Editor’结束)!
Customizers (可以忽略)
在bean层次上configure或edit一个bean。
所有的customizer 必须:
- 继承 java.awt.Component 或其子类。
- 实现 java.beans.Customizer 接口。就是实现注册 PropertyChangeListener对象的方法。
- 默认构造。
- 通过BeanInfo.getBeanDescriptor将customizer关联到目标类。
参考文档:
The Java™ Tutorials,Trail: JavaBeans(TM)
JavaBeans 官方文档学习的更多相关文章
- Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion(一)
题外话:本篇是对之前那篇的重排版.并拆分成两篇,免得没了看的兴趣. 前言 在Spring Framework官方文档中,这三者是放到一起讲的,但没有解释为什么放到一起.大概是默认了读者都是有相关经验的 ...
- Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion
本篇太乱,请移步: Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 写了删删了写,反复几次,对自己的描述很不 ...
- Spring 4 官方文档学习(十二)View技术
关键词:view technology.template.template engine.markup.内容较多,按需查用即可. 介绍 Thymeleaf Groovy Markup Template ...
- Spring 4 官方文档学习(十一)Web MVC 框架之配置Spring MVC
内容列表: 启用MVC Java config 或 MVC XML namespace 修改已提供的配置 类型转换和格式化 校验 拦截器 内容协商 View Controllers View Reso ...
- Spring Data Commons 官方文档学习
Spring Data Commons 官方文档学习 -by LarryZeal Version 1.12.6.Release, 2017-07-27 为知笔记版本在这里,带格式. Table o ...
- Spring 4 官方文档学习(十一)Web MVC 框架之resolving views 解析视图
接前面的Spring 4 官方文档学习(十一)Web MVC 框架,那篇太长,故另起一篇. 针对web应用的所有的MVC框架,都会提供一种呈现views的方式.Spring提供了view resolv ...
- Spring 4 官方文档学习(十一)Web MVC 框架
介绍Spring Web MVC 框架 Spring Web MVC的特性 其他MVC实现的可插拔性 DispatcherServlet 在WebApplicationContext中的特殊的bean ...
- Spring Boot 官方文档学习(一)入门及使用
个人说明:本文内容都是从为知笔记上复制过来的,样式难免走样,以后再修改吧.另外,本文可以看作官方文档的选择性的翻译(大部分),以及个人使用经验及问题. 其他说明:如果对Spring Boot没有概念, ...
- Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion(二)
接前一篇 Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 本篇主要内容:Spring Type Conver ...
随机推荐
- 使用poll处理任意数目个客户的单进程程序
将http://www.cnblogs.com/nufangrensheng/p/3590002.html中的select改用poll. int main(int argc, char **argv) ...
- daemon与服务(service)及重启服务的方法
简单地说,系统为了某些功能必须要提供一些服务(不论是系统本身还是网络方面),这个服务就称为service.而实现这个service的程序我们就称它为daemon.实现某个服务是需要一个daemon在后 ...
- request.getServletContext()
servlect 3.0 支持,低版本不支持,报错的话看jar包的引用.
- element-ui table 前端渲染序号 index
1.前端渲染table 序号 2.使用element ui http://element-cn.eleme.io/#/zh-CN/component/table#zi-ding-yi-suo-yin ...
- 双系统 ubuntu装完系统后 丢失原win系统启动项
sudo update-grub 可以尝试以上命令 注意这里是先装的win 后装的ubuntu
- 微信公众平台自定义菜单及高级接口PHP SDK(转)
本文介绍介绍微信公众平台自定义菜单及高级接口的PHP SDK及使用方法. 作者 方倍工作室 修正记录: 2014.05.03 v1.0 方倍工作室 http://www.cnblogs.com/txw ...
- 变动性算法源代码分析与使用示例(copy_backward、 transform、 replace_copy_if 等)
首先回顾前面的文章,我们把for_each 归类为非变动性算法,实际上它也可以算是变动性算法,取决于传入的第三个参数,即函数 指针.如果在函数内对容器元素做了修改,那么就属于变动性算法. 变动性算法源 ...
- 11g RAC 加节点 之 手动加入vip 资源
今天在给一套2节点rac 加入一个节点3时碰到几个问题: 1.原生产rac 环境私网网卡,没有使用多张冗余网卡,为保证gi 稳定性,禁用了haip: but ,埋下了一个不是坑的坑!!!!!!!!!! ...
- 解决Enter键与input 、a标签触发的事件的冲突
无论是 <button type="button" onclick="console.log('123');">123</button> ...
- laravel路由之分组路由
laravel下的分组路由可以嵌套如下: Route::group(['prefix'=>'admin'],function(){ Route::group(['prefix'=>'dtk ...