|
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
- References
- JavaBean(TM) Examples
- Invisible Bean Examples
- Running The Beans in the BeanBox
- Bean Manifest Entries
- Creating the Bean Jar
- Running the BeanBox with the New Beans
- Using the BeanBox
- Connecting Beans Together
- Visible Bean Example - SDSUButton
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
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
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
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;
}
// 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 );
}
}
// 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 );
}
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
Beans must be in a jar file with a manifest before they can be used in the
BeanBox
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
"/"
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
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
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
The BeanBox has three Windows:
ToolBox - contains loaded beans
BeanBox - used to create applications
Properties - allows you to change the values bean properties
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
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.
You will get a dialog box showing all the methods that the event can trigger
Select the one you want
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);
}
// 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();
}
// 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();
}
}
// 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;
}
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)
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)
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