SDSU CS 696 Emerging Technologies: Distributed Objects
Spring Semester, 1998
Bean Example

To Lecture Notes Index
© 1998, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 28-Apr-98

Contents of Doc 31, Bean Example

  1. References
  2. JavaBean(TM) Examples
    1. Invisible Bean Examples
    2. Running The Beans in the BeanBox
      1. Bean Manifest Entries
      2. Creating the Bean Jar
      3. Running the BeanBox with the New Beans
      4. Using the BeanBox
      5. Connecting Beans Together
    3. Visible Bean Example - SDSUButton

References


Source code that is part of the BeanBox. See /opt/BDK/demo/sunw/demo on rohan for source of the BeanBox demos

Using the Beans Development Kit 1.0: A Tutorial, Alden DeSoto, Sept 1997, Sun Microsystems

JavaBeans(TM) API Specification Version 1.01, July 24, 1997, Graham Hamilton, editor, Sun Microsystems

On-line jar documentation at: http://www.sdsu.edu/doc/jdk1.1/docs/tooldocs/solaris/jar.html


Doc 31, Bean Example Slide # 2

JavaBean(TM) Examples


The visible example is derived from the OurButton example that comes with the BeanBox from Sun

The OurButton code is copywritten by Sun


Recall that the important features of JavaBeans are:

introspection
Allows a builder tool to analyze how a bean works
customization
The appearance and behavior of a bean can be customized

events
Used to connect beans together

properties
For customization and for programmatic use

persistence
Allow the customized state to be saved and reloaded later


Doc 31, Bean Example Slide # 3

Invisible Bean Examples

SDSUReporter Bean

package beanExamples;

public class SDSUReporter
   {
   String name = "SDSU";
   int count = 0;
   
   public void setName( String name)
      {
      this.name = name;
      }
   
   public String getName()
      {
      return name;
      }
   
   public void report()
      {
      System.out.println( "Report number: " + (count++)  + 
         " from " + name );
      }
   }

A get/set pair of methods define a property

SDSUReporter has one property - name


Doc 31, Bean Example Slide # 4
SDSUClock Bean

package beanExamples;
import java.util.Vector;

public class SDSUClock extends Thread
   {
   long durationBetweenTicks;
   Vector listeners = new Vector();
   
   public SDSUClock()
      {
      this(1000);
      }
      
   public SDSUClock( long millisecondsPerTimeUnit )
      {
      durationBetweenTicks  = millisecondsPerTimeUnit;
      setPriority( Thread.MAX_PRIORITY  );
      this.start();
      }
   
   public long getDuration() 
      { 
      return durationBetweenTicks; 
      }

   public void  setDuration( long newDuration )
      {
      durationBetweenTicks = newDuration;
      }


Doc 31, Bean Example Slide # 5
// SDSUClock Bean Continued

   public synchronized void addTimeAdvancedListener(
          TimeAdvancedListener listener )
      {
      listeners.addElement( listener );
      }
      
   public synchronized void removeTimeAdvancedListener( 
         TimeAdvancedListener listener )
      {
      listeners.removeElement( listener );
      }
   
   protected void notifyListeners()
      {
      TimeAdvancedEvent time = new TimeAdvancedEvent(this);
      
      for ( int k = 0; k < listeners.size(); k++)
         {
         TimeAdvancedListener aListener = 
            (TimeAdvancedListener) listeners.elementAt( k );
         aListener.timeAdvanced( time );
         }
      }


Doc 31, Bean Example Slide # 6
// SDSUClock Bean Continued

   public void run()
      {
      try
         {
         while (true)
            {
            notifyListeners();
            sleep( durationBetweenTicks );
            }
         }
      catch ( InterruptedException simulationOver )
         { return;}
      }
   }
Non Bean Classes
package beanExamples;
public class TimeAdvancedEvent extends java.util.EventObject
   {
   public TimeAdvancedEvent( SDSUClock source)
      {
      super( source );
      }
   }

public interface  TimeAdvancedListener extends 
      java.util.EventListener
   {
   void timeAdvanced( TimeAdvancedEvent timeEvent );
   }


Doc 31, Bean Example Slide # 7
Notes

public get/set methods define a JavaBean property

SDSUClock has the properties:
duration
name
(defined in java.lang.Thread)
priority
(defined in java.lang.Thread)
daemon
(defined in java.lang.Thread)


The BeanBox uses the public constructor with no arguments to create a bean object from a bean class

Make sure that you beans have the default constructor

Serialized Beans do not need the default constructor

The add<X>Listener() / remove<X>Listener() indicate that the bean could send to its listeners of type <X> any method defined in the <X>Event class


Doc 31, Bean Example Slide # 8

Running The Beans in the BeanBox


Beans must be in a jar file with a manifest before they can be used in the BeanBox

Bean Manifest Entries

Example
Name: beanExamples/SDSUReporter.class
Java-Bean: True

Name: beanExamples/SDSUClock.class
Java-Bean: True

Name: beanExamples/TimeAdvancedEvent.class

Name: beanExamples/TimeAdvancedListener.class


Each entry is separated by blank line

Name value pairs are not case sensitive

Use forward slashes "/" on all platforms
(This means WINDOWS machines too)

The name of a class in the full class name with the "." replaced with the "/"


Doc 31, Bean Example Slide # 9
Bean Manifest Options
Name: beanExamples/SDSUReporter.class
Java-Bean: True
Depends-On: beanExamples/SDSUClock.class
Design-Time-Only: false

All the classes a depends on must be listed

Use a space separated list after the Depends-On: name or use multiple Depends-On: lines

If Design-Time-Only: is set to true then the builder tool may choose not to include the bean in the constructed Application


Doc 31, Bean Example Slide # 10

Creating the Bean Jar


In the directory ~whitney/java/whitney/beans on rohan I have a file manifest.data and a directory beanExamples

file manifest.data contains:
Name: beanExamples/SDSUReporter.class
Java-Bean: True

Name: beanExamples/SDSUClock.class
Java-Bean: True

Name: beanExamples/TimeAdvancedEvent.class

Name: beanExamples/TimeAdvancedListener.class

In directory beanExamples I have the files:
SDSUClock.java                  TimeAdvancedEvent.java
SDSUReporter.java               TimeAdvancedListener.java

Compile the files with javac *.html

Now in the directory ~whitney/java/whitney/beans create the jar file with the command:
jar -cmf manifest.data Roger.jar beanExamples/SDSUReporter.class bean Examples/SDSUClock.class beanExamples/TimeAdvancedEvent.class beanExamples/TimeAdvancedListener.class


Doc 31, Bean Example Slide # 11

Running the BeanBox with the New Beans


On rohan the BDK is located at /opt/BDK

To use the BeanBox you must have the following in your path:
/opt/BDK/beanbox/classes

then execute the script:
sh /opt/BDK/beanbox/run.sh

or the java program
java sun.beanbox.BeanBoxFrame

These should start the bean box on rohan which uses X windows

Normally one can add your jar files to the directory /opt/BDK/jars and the beanbox will automatically load your beans

Since this is shared space you will have to load the beans manual using the "LoadJar" item in the "File" menu

Doc 31, Bean Example Slide # 12

Using the BeanBox

The BeanBox has three Windows:
ToolBox - contains loaded beans
BeanBox - used to create applications
Properties - allows you to change the values bean properties




Doc 31, Bean Example Slide # 13
To add a bean to the BeanBox

Bring the ToolBox window to the front

Then click on the bean you want, then click in the BeanBox were you want the bean to be

Below I have added the SDSUClock and SDSUReporter beans to the BeanBox



Doc 31, Bean Example Slide # 14

Connecting Beans Together


First click on the bean that will generate an event
In our case it is the SDSUClock

Then in the Edit menu select the Events submenu, then the event you want to trigger an action in another bean

Then click on the bean you wish to connect to.

Doc 31, Bean Example Slide # 15
You will get a dialog box showing all the methods that the event can trigger

Select the one you want


Doc 31, Bean Example Slide # 16

Visible Bean Example - SDSUButton

package beanExamples;

import java.awt.*;
import java.awt.event.*;
import java.io.Serializable;
import java.util.Vector;

public class SDSUButton extends Canvas 
               implements Serializable, MouseListener {

   public SDSUButton() {    this("SDSU");    }

   public SDSUButton(String label) {
      super();
      this.label = label;
      addMouseListener(this);
   }

   public synchronized void paint(Graphics g) {
      int width = getSize().width;
      int height = getSize().height;

      g.setColor(getBackground());
      g.fill3DRect(0, 0, width - 1, height - 1, !down);

      g.setColor(getForeground());
      g.setFont(getFont());

      g.drawRect(2, 2, width - 4, height - 4);

      FontMetrics fm = g.getFontMetrics();
      g.drawString(label, (width - fm.stringWidth(label)) / 2, 
               (height + fm.getMaxAscent() - fm.getMaxDescent()) / 2);
   }


Doc 31, Bean Example Slide # 17
// MouseListener methods

   public void mouseClicked(MouseEvent evt) { }
   public void mouseEntered(MouseEvent evt) { }
   public void mouseExited(MouseEvent evt) { }

   public void mousePressed(MouseEvent evt) {
      if (!isEnabled()) {
         return;
      }
      down = true;
      repaint();
   }

   public void mouseReleased(MouseEvent evt) {
      if (!isEnabled()) {
         return;
      }
      if (down) {
         fireAction();  // notifies listeners
         down = false;
         repaint();
      }
   }

   // Size information for the display of the button
   public Dimension getPreferredSize() {
      FontMetrics fm = getFontMetrics(getFont());
      return new Dimension(fm.stringWidth(label) + TEXT_XPAD, 
         fm.getMaxAscent() + fm.getMaxDescent() + TEXT_YPAD);
   }

   public Dimension getMinimumSize() {
      return getPreferredSize();
   }


Doc 31, Bean Example Slide # 18
// setLabel and getLabel define the Label property
   public void setLabel(String newLabel) {
      label = newLabel;
      sizeToFit();
   }

   public String getLabel() {
      return label;
   }

   private void sizeToFit() {
      Dimension d = getPreferredSize();
      setSize(d.width, d.height);
      Component p = getParent();
      if (p != null) {
         p.invalidate();
         p.doLayout();
      }
   }



Doc 31, Bean Example Slide # 19
// Methods for registering/deregistering event listeners

   public synchronized void addActionListener(ActionListener l) {
      pushListeners.addElement(l);
   }

   public synchronized void removeActionListener(ActionListener l) {
      pushListeners.removeElement(l);
   }

   public void fireAction() {
      Vector targets;
      synchronized (this) {
         targets = (Vector) pushListeners.clone();
      }
      ActionEvent actionEvt = new ActionEvent(this, 0, null);
      for (int i = 0; i < targets.size(); i++) {
         ActionListener target = (ActionListener)targets.elementAt(i);
         target.actionPerformed(actionEvt);
      }
   }

   private Vector pushListeners = new Vector();
   private String label;
   private boolean down;

   static final int TEXT_XPAD = 12;
   static final int TEXT_YPAD = 8;
}


Doc 31, Bean Example Slide # 20
SDSUButton Parent Classes


Properties

Properties are defined by a set/get methods

SDSUButton has the following properties:
label
foreground (in Component)
background (in Component)
font (in Component)
name (in Component)


Doc 31, Bean Example Slide # 21
Events Generated

Component has the following listeners:

addComponentListener(ComponentListener)
Adds the specified component listener to receive component events from this component
addFocusListener(FocusListener)
Adds the specified focus listener to receive focus events from this component
addKeyListener(KeyListener)
Adds the specified key listener to receive key events from this component
addMouseListener(MouseListener)
Adds the specified mouse listener to receive mouse events from this component
addMouseMotionListener(MouseMotionListener)
Adds the specified mouse motion listener to receive mouse motion events from this component

The interface java.awt.event.MouseListener declares the following interfaces:
mouseClicked(MouseEvent)
mouseEntered(MouseEvent)
mouseExited(MouseEvent)
mousePressed(MouseEvent)
mouseReleased(MouseEvent)


Doc 31, Bean Example Slide # 22
The Events Menu of SDSUButton
Demo of connecting two SDSUButtons to Juggler

Use two buttons

Connect the "Events - action - actionPerformed" event of one button to the startJuggling method of the Juggler

Connect the "Events - action - actionPerformed" event of the other button to the stopJuggling method of the Juggler

Have one button control two Jugglers

Use the mouseEntered event of the JellyBean to start a Juggler

Copyright © 1998 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
All rights reserved.

visitors since 28-Apr-98