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 ...
随机推荐
- Java Executor 线程池
- java-----instanceof与getClass的区别
在比较一个类是否和另一个类属于同一个类实例的时候,我们通常可以采用instanceof和getClass两种方法通过两者是否相等来判断,但是两者在判断上面是有差别的,下面从代码中看看区别: publi ...
- oracle 导入Excel数据
oracle 导入excel数据 CreateTime--2018年1月30日14:58:51 Author:Marydon 通过plsql实现 1.准备工作 Excel中的字段名称,必须和表结构 ...
- js判断是否包含指定字符串
CreateTime--2017年2月28日09:37:06Author:Marydonjs判断是否包含指定字符串 var inputValue = "thunder://piaohua ...
- QQ窗体的控制,同步异步打开360网盘,控制360网盘窗体的移动
1.通过system启动飞秋进程的方式: 2.Windows下杀死进程的方式是:taskkill /f/im QQ.exe.截图例如以下: watermark/2/text/aHR0cDovL2 ...
- ERRORS:<class 'Salesman.admin.UsrMngUserAdmin'>: (admin.E005) Both 'fieldsets' and 'fields' are specified.
在使用django admin的过程中 遇到了这个错误 . Both 'fieldsets' and 'fields' are specified. django.core.management.ba ...
- vim手记
1.normal 模式进入edit模式 i(a,o),进入 command 模式 :,回到normal模式Esc(ctrl+c,ctrl+[)2.help urs_toc 进入帮助文档目录,退出目录: ...
- Decoration5:引入Actuator进行站点监控
1.添加依赖 2.重启应用 3.下图显示了一些默认的监控端点 这是数据可以在前台用来做饼图和柱状图什么的,不过实际上我们现在还用不到,于是就不深入研究
- CShopDialog类
#ifndef SHOP_H #define SHOP_H #include "XWidget.h" #include "GameConfig.h" class ...
- 每日英语:Dishing the Dirt on Hand-Washing Guidelines
Americans aren't washing their hands nearly as often and as thoroughly as they should, according to ...