接下的程序例子稍微复杂一些,尽管这没有什么价值。这个程序是一张不论鼠标何时移动都围绕它画一个小圆的,并且一个动作接收器被激活。画布。当按下鼠标键时,我们可以改变的属性是圆的大小,除此之外还有被显示文字的色彩,大小,内容。BangBean同样拥有它自己的addActionListener()和removeActionListener()方法,因此我们可以附上自己的当用户单击在BangBean上时会被激活的接收器。这样,我们将能够确认可支持的属性和事件:
//: BangBean.java
// A graphical Bean
package bangbean;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
public class BangBean extends Canvas
implements Serializable {
protected int xm, ym;
protected int cSize = 20; // Circle size
protected String text = "Bang!";
protected int fontSize = 48;
protected Color tColor = Color.red;
protected ActionListener actionListener;
public BangBean() {
addMouseListener(new ML());
addMouotionListener(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);
}
// This is a unicast listener, which is
// the simplest form of listener management:
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();
// Call the listener's method:
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();
}
}
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
// Testing the BangBean:
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);
}
// During testing, send action information
// to the console:
static class BBL implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("BangBean action");
}
}
} ///:~
最重要的是我们会注意到BangBean执行了这种串联化的接口。这意味着应用程序构建工具可以在程序设计者调整完属性值后利用串联为BangBean贮藏所有的信息。当Bean作为运行的应用程序的一部分被创建时,那些被贮藏的属性被重新恢复,因此我们可以正确地得到我们的设计。
我们能看到通常同Bean一起运行的所有的字段都是专用的——允许只能通过方法来访问,通常利用“属性”结构。
当我们注视着addActionListener()的签名时,我们会注意到它可以产生出一个TooManyListenerException(太多接收器异常)。这个异常指明它是一个单一的类型的,意味着当事件发生时,它只能通知一个接收器。一般情况下,我们会使用具有多种类型的事件,以便一个事件通知多个的接收器。但是,那样会陷入直到下一章我们才能准备好的结局中,因此这些内容会被重新回顾(下一个标题是“Java Beans 的重新回顾”)。单一类型的事件回避了这个难题。
当我们按下鼠标键时,文字被安入BangBean中间,并且如果动作接收器字段存在,它的actionPerformed()方法就被调用,创建一个新的ActionEvent对象在处理过程中。无论何时鼠标移动,它的新座标将被捕捉,并且画布会被重画(像我们所看到的抹去一些画布上的文字)。
main()方法增加了允许我们从命令行中测试程序的功能。当一个Bean在一个开发环境中,main()方法不会被使用,但拥有它是绝对有益的,因为它提供了快捷的测试能力。无论何时一个ActionEvent发生,main()方法都将创建了一个帧并安置了一个BangBean在它里面,还在BangBean中附上了一个简单的动作接收器以打印到控制台。当然,一般来说应用程序构建工具将创建大多数的Bean的代码。当我们通过BeanDumper或者安放BangBean到一个可激活Bean的开发环境中去运行BangBean时,我们会注意到会有很多额外的属性和动作明显超过了上面的代码。那是因为BangBean从画布中继承,并且画布就是一个Bean,因此我们看到它的属性和事件同样的合适。
¥498.00
¥399.00
¥299.00
¥29.00