Wednesday 29 March 2017

Introspection & Developing a Simple Bean Using the BDK - Java Tutorials

Introspection

Introspection is the process of analyzing a Bean to determine its capabilities. This is an essential feature of the Java Beans API, because it allows an application builder tool to present information about a component to a software designer. Without introspection, the Java Beans technology could not operate.

There are two ways in which the developer of a Bean can indicate which of its properties, events, and methods should be exposed by an application builder tool. With the first method, simple naming conventions are used. These allow the introspection mechanisms to infer information about a Bean. In the second way, an additional class is provided that explicitly supplies this information. The first approach is examined here. The second method is described later.

The following sections indicate the design patterns for properties and events that enable the functionality of a Bean to be determined.


Design Patterns for Properties

A property is a subset of a Bean’s state. The values assigned to the properties determine the behavior and appearance of that component. This section discusses three types of properties: simple, Boolean, and indexed.

Simple Properties
A simple property has a single value. It can be identified by the following design patterns, where N is the name of the property and T is its type.

      public T getN( );
      public void setN(T arg);

A read/write property has both of these methods to access its values. A read-only property has only a get method. A write-only property has only a set method. The following listing shows a class that has three read/write simple properties:

  public class Box {
    private double depth, height, width;
    public double getDepth( ) {
      return depth;
    }
    public void setDepth(double d) {
      depth = d;
    }
    public double getHeight( ) {
      return height;
    }
    public void setHeight(double h) {
      height = h;
    }
    public double getWidth( ) {
      return width;
    }
    public void setWidth(double w) {
      width = w;
    }
  }


Boolean Properties
A Boolean property has a value of true or false. It can be identified by the following design patterns, where N is the name of the property:

      public boolean isN( );
      public boolean getN( );
      public void setN(boolean value);

Either the first or second pattern can be used to retrieve the value of a Boolea property. However, if a class has both of these methods, the first pattern is used. The following listing shows a class that has one Boolean property:

  public class Line {
    private boolean dotted = false;
    public boolean isDotted( ) {
      return dotted;
    }
    public void setDotted(boolean dotted) {
      this.dotted = dotted;
    }
  }


Indexed Properties
An indexed property consists of multiple values. It can be identified by the following design patterns, where N is the name of the property and T is its type:

      public T getN(int index);
      public void setN(int index, T value);
      public T[ ] getN( );
      public void setN(T values[ ]);

The following listing shows a class that has one read/write indexed property:

  public class PieChart {
    private double data[ ];
    public double getData(int index) {
      return data[index];
    }
    public void setData(int index, double value) {
      data[index] = value;
    }
    public double[ ] getData( ) {
      return data;
    }
    public void setData(double[ ] values) {
      data = new double[values.length];
      System.arraycopy(values, 0, data, 0, values.length);
    }
  }


Design Patterns for Events

Beans use the delegation event model that was discussed earlier in this book. Beans can generate events and send them to other objects. These can be identified by the following design patterns, where T is the type of the event:

      public void addTListener(TListener eventListener);
      public void addTListener(TListener eventListener) throws TooManyListeners;
      public void removeTListener(TListener eventListener);

These methods are used by event listeners to register an interest in events of a specific type. The first pattern indicates that a Bean can multicast an event to multiple listeners. The second pattern indicates that a Bean can unicast an event to only one listener. The third pattern is used by a listener when it no longer wishes to receive a specific type of event notification from a Bean.

The following listing outlines a class that notifies other objects when a temperature value moves outside a specific range. The two methods indicated here allow other objects that implement the TemperatureListener interface to receive notifications when this occurs.

  public class Thermometer {
    public void addTemperatureListener(TemperatureListener tl) {
      ...
    }
    public void removeTemperatureListener(TemperatureListener tl) {
      ...
    }
  }

Methods
Design patterns are not used for naming nonproperty methods. The introspection mechanism finds all of the public methods of a Bean. Protected and private methods are not presented.




Developing a Simple Bean Using the BDK

This section presents an example that shows how to develop a simple Bean and connect it to other components via the BDK. Our new component is called the Colors Bean. It appears as either a rectangle or ellipse that is filled with a color. A color is chosen at random when the Bean begins execution. A public method can be invoked to change it. Each time the mouse is clicked on the Bean, another random color is chosen. There is one boolean read/write property that determines the shape.

The BDK is used to lay out an application with one instance of the Colors Bean and one instance of the OurButton Bean. The button is labeled “Change.” Each time it is pressed, the color changes.


Create a New Bean

Here are the steps that you must follow to create a new Bean:
  1. Create a directory for the new Bean.
  2. Create the Java source file(s).
  3. Compile the source file(s).
  4. Create a manifest file.
  5. Generate a JAR file.
  6. Start the BDK.
  7. Test.

The following sections discuss each of these steps in detail.

Create a Directory for the New Bean
You need to make a directory for the Bean. To follow along with this example, create c:\bdk\demo\sunw\demo\colors. Then change to that directory.

Create the Source File for the New Bean
The source code for the Colors component is shown in the following listing. It is
located in the file Colors.java.

The import statement at the beginning of the file places it in the package named sunw.demo.colors. Recall from Chapter 9 that the directory hierarchy corresponds to the package hierarchy. Therefore, this file must be located in a subdirectory named sunw\demo\colors relative to the CLASSPATH environment variable. The color of the component is determined by the private Color variable color, and its shape is determined by the private boolean variable rectangular.

The constructor defines an anonymous inner class that extends MouseAdapter and overrides its mousePressed( ) method. The change( ) method is invoked in response to mouse presses. The component is initialized to a rectangular shape of 200 by 100 pixels. The change( ) method is invoked to select a random color and repaint the component.

The getRectangular( ) and setRectangular( ) methods provide access to the one property of this Bean. The change( ) method calls randomColor( ) to choose a color and then calls repaint( ) to make the change visible. Notice that the paint( ) method uses the rectangular and color variables to determine how to present the Bean.

  // A simple Bean.
  package sunw.demo.colors;
  import java.awt.*;
  import java.awt.event.*;
  public class Colors extends Canvas {
    transient private Color color;
    private boolean rectangular;
    public Colors() {
      addMouseListener(new MouseAdapter() {
        public void mousePressed(MouseEvent me) {
          change();
        }
      });
      rectangular = false;
      setSize(200, 100);
      change();
    }
    public boolean getRectangular() {
      return rectangular;
    }
    public void setRectangular(boolean flag) {
      this.rectangular = flag;
      repaint();
    }
    public void change() {
      color = randomColor();
      repaint();
    }
    private Color randomColor() {
      int r = (int)(255*Math.random());
      int g = (int)(255*Math.random());
      int b = (int)(255*Math.random());
      return new Color(r, g, b);
    }
    public void paint(Graphics g) {
      Dimension d = getSize();
      int h = d.height;
      int w = d.width;
      g.setColor(color);
      if(rectangular) {
        g.fillRect(0, 0, w-1, h-1);
      }
      else {
        g.fillOval(0, 0, w-1, h-1);
      }
    }
  }

Compile the Source Code for the New Bean
Compile the source code to create a class file. Type the following:

  javac Colors.java.

Create a Manifest File
You must now create a manifest file. First, switch to the c:\bdk\demo directory. This is the directory in which the manifest files for the BDK demos are located. Put the source code for your manifest file in the file colors.mft. It is shown here:

  Name: sunw/demo/colors/Colors.class
  Java-Bean: True

This file indicates that there is one .class file in the JAR file and that it is a Java Bean. Notice that the Colors.class file is in the package sunw.demo.colors and in the subdirectory sunw\demo\colors relative to the current directory.

Generate a JAR File
Beans are included in the ToolBox window of the BDK only if they are in JAR files in the directory c:\bdk\jars. These files are generated with the jar utility. Enter the following:

  jar cfm ..\jars\colors.jar colors.mft sunw\demo\colors\*.class

This command creates the file colors.jar and places it in the directory c:\bdk\jars. (You may wish to put this in a batch file for future use.)

Start the BDK
Change to the directory c:\bdk\beanbox and type run. This causes the BDK to start. You should see three windows, titled ToolBox, BeanBox, and Properties. The ToolBox window should include an entry labeled “Colors” for your new Bean.

Create an Instance of the Colors Bean
After you complete the preceding steps, create an instance of the Colors Bean in the BeanBox window. Test your new component by pressing the mouse anywhere within its borders. Its color immediately changes. Use the Properties window to change the rectangular property from false to true. Its shape immediately changes.

Create and Configure an Instance of the OurButton Bean
Create an instance of the OurButton Bean in the BeanBox window. Then follow these steps:
  1. Go to the Properties window and change the label of the Bean to “Change”. You should see that the button appearance changes immediately when this property is changed.
  2. Go to the menu bar of the BeanBox and select Edit | Events | action | actionPerformed.
  3. Move the cursor so that it is inside the Colors Bean display area, and click the left mouse button. You should see the Event Target Dialog dialog box.
  4. The dialog box allows you to choose a method that should be invoked when this button is clicked. Select the entry labeled “change” and click the OK button. You should see a message box appear very briefly, stating that the tool is “Generating and compiling adaptor class.”
  5. Click on the button. You should see the color change. You might want to experiment with the Colors Bean a bit before moving on.

No comments:

Post a Comment