继承和多形态性是面向对象编程的精华,但在大多数情况下当我们创建一个应用程序时,我们真正最想要的 恰恰是我们最需要的组件。我们希望在我们的设计中设置这些部件就像电子工程师在电路板上创造集成电路 块一样(在使用Java 的情况下,就是放到WEB页面上)。这似乎会成为加快这种“模块集合”编制程序方法 的发展。
可视化的编程工具如此成功的原因是它们明显加快构建的应用程序的处理 过程——当然,用户接口作为应用程序的一部分同样的好。
1. 什么是 Bean
在Java 的文件中,命名规则被错误地曲解为“设计范式”。这十分的不幸,因为设计范式(参见第 16章) 惹来不少的麻烦。命名规则不是设计范式,它是相当的简单:
(1) 因为属性被命名为 xxx,我们代表性的创建两个方法:getXxx()和 setXxx()。注意 get或 set后的第一 个字母小写以产生属 性名。“get”和“set”方法产生同样类型的自变量。“set”和“get”的属性名和类 型名之间没有关系。
(2) 对于布尔逻辑型属性,我们可以使用上面的“get”和“set”方法,但我们也可以用“is”代替 “ get”。
(3) Bean 的普通方法不适合上面的命名规则,但它们是公用的。
(4) 对于事件,我们使用“listener(接收器)”方法。这种方法完全同我们看到过的方法相同。
【案例1】一个简单的java bean 程序
package jbean;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
class Spots
{
}
public class Frog
{
private int jumps;
private Color color;
private Spots spots;
private boolean jmpr;
public int getJumps()
{
return jumps;
}
public void setJumps(int newJumps)
{
jumps = newJumps;
}
public Color getColor()
{
return color;
}
public void setColor(Color newColor)
{
color = newColor;
}
public Spots getSpots()
{
return spots;
}
public void setSpots(Spots newSpots)
{
spots = newSpots;
}
public boolean isJumper()
{
return jmpr;
}
public void setJumper(boolean j)
{
jmpr = j;
}
public void addActionListener(ActionListener l)
{
}
public void removeActionListener(ActionListener l)
{
}
public void addKeyListener(KeyListener l)
{
}
public void removeKeyListener(KeyListener l)
{
}
public void croak()
{
System.out.println("Ribbet!");
}
}
我们可看到 Bean 就是一个类。通常,所有我们的字段会被作为专用,并且可以接近的唯一办法是通过 方法。紧接着的是命名规则,属性是jump,color,jumper,spots(注意这些修改是在第一个字母在属性名 的情况下进行的)。虽然内部确定的名字同最早的三个例子的属性名一样,在jumper中我们可以看到属性名 不会强迫我们使用任何特殊的内部可变的名字(或者,真的拥有一些内部的可变的属性名)。 Bean 事件的句柄是ActionEvent 和KeyEvent,这是根据有关接收器的“add”和“remove”命名方法得出 的。最后我们可以注意到普通的方法croak()一直是 Bean 的一部分,仅仅是因为它是一个公共的方法,而不 是因为它符合一些命名规则。
2. 用Introspector提取BeanInfo
【案例】获取bean信息
package awt.test;
import java.beans.*;
import java.lang.reflect.*;
public class BeanDumper
{
public static void dump(Class bean)
{
BeanInfo bi = null;
try
{
bi = Introspector.getBeanInfo(bean, java.lang.Object.class);
} catch (IntrospectionException ex)
{
System.out.println("Couldn't introspect " + bean.getName());
System.exit(1);
}
PropertyDescriptor[] properties = bi.getPropertyDescriptors();
for (int i = 0; i < properties.length; i++)
{
Class p = properties[i].getPropertyType();
System.out.println("Property type:\n " + p.getName());
System.out.println("Property name:\n " + properties[i].getName());
Method readMethod = properties[i].getReadMethod();
if (readMethod != null)
System.out.println("Read method:\n " + readMethod.toString());
Method writeMethod = properties[i].getWriteMethod();
if (writeMethod != null)
System.out
.println("Write method:\n " + writeMethod.toString());
System.out.println("====================");
}
System.out.println("Public methods:");
MethodDescriptor[] methods = bi.getMethodDescriptors();
for (int i = 0; i < methods.length; i++)
System.out.println(methods[i].getMethod().toString());
System.out.println("======================");
System.out.println("Event support:");
EventSetDescriptor[] events = bi.getEventSetDescriptors();
for (int i = 0; i < events.length; i++)
{
System.out.println("Listener type:\n "
+ events[i].getListenerType().getName());
Method[] lm = events[i].getListenerMethods();
for (int j = 0; j < lm.length; j++)
System.out.println("Listener method:\n " + lm[j].getName());
MethodDescriptor[] lmd = events[i].getListenerMethodDescriptors();
for (int j = 0; j < lmd.length; j++)
System.out.println("Method descriptor:\n "
+ lmd[j].getMethod().toString());
Method addListener = events[i].getAddListenerMethod();
System.out.println("Add Listener Method:\n "
+ addListener.toString());
Method removeListener = events[i].getRemoveListenerMethod();
System.out.println("Remove Listener Method:\n "
+ removeListener.toString());
System.out.println("====================");
}
}
public static void main(String[] args)
{
Class c = null;
try
{
c = Class.forName("awt.test.Person");
} catch (ClassNotFoundException ex)
{
System.err.println("Couldn't find " + args[0]);
System.exit(0);
}
dump(c);
}
}
其中用来测试的Java Bean ,Person类
package awt.test;
import java.io.Serializable;
public class Person implements Serializable
{
private String name;
private int age;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public Person()
{
super();
}
public Person(String name, int age)
{
super();
this.name = name;
this.age = age;
}
public void show(String a, int b)
{
System.out.println("show( )");
}
}
这里面感觉就是用introspector这个取获取bean里面的属性,其中属性包括属性的类型,属性名。 bean里面的方法,其中方法包括方法的各个属性,以及bean里面的方法以及bean里面的事件。
3. 一个更复杂的Bean
package awt.test;
import java.awt.Canvas;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
public class BangBean extends Canvas implements Serializable
{
/**
*
*/
private static final long serialVersionUID = 1L;
protected int xm;
protected int ym;
protected int cSize = 20;
protected String text = "Bang!";
protected int fontSize = 48;
protected Color tColor = Color.red;
protected ActionListener actionListener;
public BangBean()
{
addMouseListener(new ML());
addMouseMotionListener(new MML());
}
public int getCircleSize()
{
return cSize;
}
public void setCircleSize(int newSize)
{
cSize = newSize;
}
public String getBangText()
{
return text;
}
public void setBangText(String newText)
{
text = newText;
}
public int getFontSize()
{
return fontSize;
}
public void setFontSize(int newSize)
{
fontSize = newSize;
}
public Color getTextColor()
{
return tColor;
}
public void setTextColor(Color newColor)
{
tColor = newColor;
}
public void paint(Graphics g)
{
g.setColor(Color.black);
g.drawOval(xm - cSize / 2, ym - cSize / 2, cSize, cSize);
}
public void addActionListener(ActionListener l)
throws TooManyListenersException
{
if (actionListener != null)
throw new TooManyListenersException();
actionListener = l;
}
public void removeActionListener(ActionListener l)
{
actionListener = null;
}
class ML extends MouseAdapter
{
public void mousePressed(MouseEvent e)
{
Graphics g = getGraphics();
g.setColor(tColor);
g.setFont(new Font("TimesRoman", Font.BOLD, fontSize));
int width = g.getFontMetrics().stringWidth(text);
g.drawString(text, (getSize().width - width) / 2,
getSize().height / 2);
g.dispose();
if (actionListener != null)
actionListener.actionPerformed(new ActionEvent(BangBean.this,
ActionEvent.ACTION_PERFORMED, null));
}
}
class MML extends MouseMotionAdapter
{
public void mouseMoved(MouseEvent e)
{
xm = e.getX();
ym = e.getY();
repaint();
}
}
static class BBL implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
System.out.println("BangBean action");
}
}
public Dimension getPreferredSize()
{
return new Dimension(200, 200);
}
public static void main(String[] args)
{
BangBean bb = new BangBean();
try
{
bb.addActionListener(new BBL());
} catch (TooManyListenersException e)
{
}
Frame aFrame = new Frame("BangBean Test");
aFrame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
aFrame.add(bb, BorderLayout.CENTER);
aFrame.setSize(300, 300);
aFrame.setVisible(true);
}
}
本文探讨了JavaBean的设计规则及BeanInfo的提取方法,解释了如何通过Introspector工具获取Bean属性、方法和事件信息。同时介绍了如何利用可视化编程工具加速应用程序构建过程,以及在实际应用中创建复杂Bean实例的过程。
11万+

被折叠的 条评论
为什么被折叠?



