返回介绍

13.18.3 一个更复杂的 Bean

发布于 2024-10-15 23:56:30 字数 4373 浏览 0 评论 0 收藏 0

接下的程序例子稍微复杂一些,尽管这没有什么价值。这个程序是一张不论鼠标何时移动都围绕它画一个小圆的 弧5蔽颐前聪率蟊昙保谄聊恢醒胂允疽桓鲎帧奥 ang!”,并且一个动作接收器被激活。画布。当按下鼠标键时,我们可以改变的属性是圆的大小,除此之外还有被显示文字的色彩,大小,内容。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());
    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);
  }
  // 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,因此我们看到它的属性和事件同样的合适。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文