Given by Nancy McCracken, Geoffrey C. Fox, Wojtek Furmanski at Basic Information Track Computational Science Course CPS616 on March 25 1998. Foils prepared March 23 98
Outside Index
Summary of Material
General Issues -- why Java Beans are important |
An Example JavaBean |
Detailed Technologies of JavaBeans
|
Outside Index Summary of Material
Geoffrey Fox, Nancy McCracken, |
Wojtek Furmanski |
Syracuse University NPAC |
111 College Place Syracuse NY 13244 4100 |
3154432163 |
General Issues -- why Java Beans are important |
An Example JavaBean |
Detailed Technologies of JavaBeans
|
O'Reilly: Java in a Nutshell by David Flanagan describes JavaBeans as part of extensive JDK1.1 description |
SunSoft Press Java Series: coreJava 1.1, Volume II Advanced Features by Cay Horstmann and Gary Cornell has a chapter with good programming examples on all features of JavaBeans. |
Sybex: Java 1.1 Developer's Handbook by Philip Heller, Simon Roberts, Peter Seymour and Tom McGinn is a very detailed description of JDK1.1 including JavaBeans |
O'Reilly: Developing JAVA Beans by Robert Englander is a focussed description of JavaBeans from a Java Programmers point of view |
Coriolis Group Books: Web developer's guide to javabeans by Jalal Feghhi is an interesting discussion from ComponentWare perspective. Also has CORBA DCOM ActiveX OpenDoc |
See resources listed at http://www.npac.syr.edu/projects/tutorials/JavaBeans |
They are Java's implementation of "component-based" visual programming |
This modern software engineering technique produces a new approach to libraries which become a "software component infrastructure(SCI)" |
There is a visual interface to discovery of and setting of values of and information about parameters used in a particular software component |
JavaBeans uses the event model of JDK1.1 to communicate between components
|
The visual interface allows inspection of and implementation of both individual beans and their linkage . This visual construction of linkage allows one to form nontrivial programs with multiple communicating components |
Apart from the event mechanism which is a communication/linkage mechanism, ComponentWare (and JavaBeans in particular) "just" give a set of universal rules (needed for interoperability) for rather uncontroversial (albeit good) object-oriented and visual programming practices
|
A JavaBean is "just" a Java Object which is part of some application for the end-user. |
JavaBeans implement the JDK1.1 event linkage mechanism for exchanging changes in values of properties and hence invoking responses to these changes. |
JavaBeans implement JDK1.1 Object Serialization to represent JavaBeans in "databases" (disk files) and hence define JavaBeans as persistent objects |
JavaBeans do not need to implement any particular class or interface.
|
These patterns are "discovered" automatically by the "introspection" capability of the reflection API in Java which is invoked by the BeanBox |
A BeanBox is a visual interface that displays (and allows changes to be made to) the properties of a JavaBean and further allows one to see and change the linkage between JavaBeans. |
A JavaBean consists of Java Code and possible associated files such as one or more icons, an image or two, a help file etc. This collection of entities is stored in a jar file which is based on the well-known UNIX tar file concept |
JavaBeans are naturally used as distributed objects in CORBA and can be linked to both JDBC (and hence databases) and COM from Microsoft. |
There is a Java native distributed communication model RMI (Remote Method Invocation) which provides CORBA like capabilities for a pure Java world
|
JavaBeans use the same event model as the AWT to communicate between Beans. This involves an indirect structure with Listeners acting as a bridge or broker between Sources (of information) and Sinks or what is synonymous observers. |
Source Bean |
Listener |
Sink Bean |
2) Notification of need to communicate |
1) |
Source Bean |
Sink Bean |
3) Communicate |
In the simplest case when one combines sink with listener, then one typically finds cycle (with any number of sinks)
|
To a standard hello world Java class, we add a (read/write) property by defining get and set functions in the correct pattern. |
import java.awt.* |
public class HelloBean extends java.applet.Applet |
implements java.io.Serializable |
{ String sname = "World"; |
public void setName (String newname) |
{ sname = newname; } |
public String getName ( ) |
{ return sname; } |
Enables saving as Object |
Class variable for value of property |
Get and set methods define a property called Name with a value of type String |
Additional methods make the bean have a visualization (canvas) |
public Dimension getMinimumSize() |
{ return new Dimension (250, 70); } |
public void paint(Graphics g) |
{Font f = new Font("TimesRoman", Font.BOLD, 36); |
g.setFont(f); |
g.setColor(Color.red); |
g.drawString("Hello " + sname + "!", 5, 50); |
} |
} |
Use the paint method to draw on the canvas |
New JDK1.1 method to tell Layout manager the minimum size of the canvas - also defines a (read only) property. |
After compiling the .java file, convert the .class file to a JAR file. |
Among the archive options are
|
Run the BeanBox and use the Loadjar command to open your new Bean. |
Use as many copies as you want, using the property editor to change the name. |
This is Java's version of a UNIX tar file and contains a variety of files including .class, image, sound, HTML pages |
The JAR file is stored in compressed (zip) fashion and can also be signed using standard digital signature techniques.
|
There is a "control" file called a manifest which inter alia is used to identify any JavaBean present. It also specifies message digest algorithm |
JavaBeans must be stored in JAR files and must be identified in manifest |
JAR files can be accessed from HTML using <APPLET> tag
|
Java looks first in .jar files for requested class |
Giving a set method defines a write property, and a get method defines a read property, according to this pattern: public void set<PropertyName>(<PropertyType> value); public <PropertyType> get<PropertyName> ( ); |
If the property type is boolean, the get() method can be replaced or augmented by a method: public boolean is<PropertyName> ( ); |
Properties can also have arrays of values. For example, you can have a property named StockList, which had an indexed collection of Strings as its value: public String [ ] getStockList ( ); public void setStockList ( String [ ] values); |
And you can give methods to access individual values: public String getStockList (int index); public void setStockList (int index, String value); |
Consider the standard example of hooking up two buttons to start and stop the Juggler animation bean. |
First we place a button and name it start. We want to hook up its actionEvent with the method called start() in the Juggler, which starts the animation. |
The BeanBox allows us to select the actionPerformed event from the "button push" menu, select the Juggler bean to be the target, and select its start method. |
What this does is to create a class that implements an ActionListener (or inherits from the ActionListener adapter class). |
This is the automatically generated file for the Juggler: package tmp.sun.beanbox; public class __Hookup_140a49964da implements java.awt.event.ActionListener, java.io.Serializable { private sunw.demo.juggler.Juggler target; public void setTarget(sunw.demo.juggler.Juggler t) { target = t; } public void actionPerformed (java.awt.event.ActionEvent arg0) { target.startJuggling(); } } |
A property is bound if a change to its value can be reported as an event to other beans. |
One way is to inherit from the class: public class java.beans.PropertyChangeSupport implements java.io.Serializable ... public synchronized void addPropertyChangeListener ... public synchronized void removePropertyChangeListener ... public void firePropertyChange (String propertyName, Object oldValue, Object newValue); |
This class behaves as a source of events. |
The class with the bound property creates an instance of the PropertyChangeSupport class: PropertyChangeSupport pcs = new PropertyChangeSupport(this); and uses its add and remove listener methods. |
Then the class with the bound property must call firePropertyChange whenever it changes the value of the bound property (i.e. in the set method of the property). |
Any class which wants to be notified of changes to the bound property must implement the PropertyChangeListener and supply a method propertyChange that will be called with a PropertyChangeEvent. This method can event methods getOldValue() and getNewValue. |
A related concept is when another bean wants to have a possible veto over a change to a property. |
The set method of the property throws an exception called java.beans.PropertyVetoException. |
The object must also support (by having add and remove methods) a VetoableChangeListener. |
Then each bean that wants to be able to veto property changes implements VetoableChangeListener by supplying the method vetoableChange(PropertyChangeEvent e). |
If more than one bean wants to veto property changes, then it may be quite complicated to work out when to keep the old value or move to the new value. |
Persistence of an object implies that one can save its value to some permanent store (e.g. a disk) and read it back |
This is implemented using Serializable (default saving) or Externalizable (user defined saving) |
In saving a Java Object, we save the values of data members but assume that the entity reading back object has access to class definition so that one just needs data member values to define instance
|
One needs to flatten the hierarchical linkage of objects to any root Java object |
In diagram, one needs to output members of A, B, C and D with D only output once! |
Object A |
Object B |
Object C |
Object D |
Root object |
Leaf object |
The Serialization interface is essentially a flag as there are NO methods or data attached to this interface -- implementing Serialization implies your willingness to be saved using default Java mechanism! |
The Serialization process is typically implemented by a container (Java Applet, Application, Java Beans Container) |
Typically one serializes to an output stream and deserializes from an input stream |
DataOutput Interface describes streams that can write out data in a machine independent fashion |
ObjectOutputStream class extends DataOutput (and an ObjectOutput Interface) and defines methods to write out variables of all the primitive types with a general
|
java.awt.Component class implements the Serializable interface and any bean extending this class or any of its subclasses is automatically Serializable and hence can be persistent |
Note Object class is not Serializable and so one must inherit from a subclass of Object that is Serializable in order to automatically get this property |
One can explicitly implement the Serializable Interface by supplying writeObject() and readObject() |
Beans should store references to external Beans as transient as linkage is responsibility of BeanBox |
Externalizable Objects must implement writeExternal() and readExternal() methods for user implemented persistency |
Introspection refers to the process by which JavaBeans are inspected to discover their characteristics. This a combination of
|
The Java Core Reflection API allows one to determine information about objects at runtime.
|
The reflection API is used in two ways:
|
First one invokes for any Object obj
|
Second process instance cl of class Class, has methods
|
These return public instances only |
Thirdly process arrays like Field, Method, Constructor etc. which are in java.lang.reflect and have a whole set of methods to find out further information including
|
So far the beans we've seen have used standard patterns to expose their properties, methods, and events to a builder's tool. For more general introspection, you can proved a class specifically to describe the bean. |
This class implements the java.beans.BeanInfo interface. |
If you have a Bean class named Xyz, the its beaninfo class is named XyzBeanInfo. |
If you don't want to supply new versions of all the methods in the BeanInfo interface, you can extend the class java.beans.SimpleBeanInfo, which provide null methods. For any method which is null, a builder's tool will use the standard reflection to find standard properties, etc.
|
getAdditionalBeanInfo() getBeanDescriptor() getDefaultEventIndex() getDefaultPropertyIndex() getEventSetDescriptors() getIcon() getMethodDescriptors() getPropertyDescriptors() |
BeanInfo can supply
|
BeanDescriptor is one of entities you can get from BeanInfo and this holds overall information about the Bean |
The Property Sheet box uses default java classes to read and write any property. You can provide your own methods by implementing the java.beans.PropertyEditor class. |
In addition, if you want to do more complex design time customization of the bean, possibly involving many properties, you can implement java.beans.Customizer. You may present a panel for the user to change many properties or run other methods of the bean class. |
Bean |
Bean |
Bean |
Bean |
JDB |
JDBC |
Java Beans Framework |
Java Server |
CORBA Server |
Database Server |
RMI |
IIOP |
Particular |
Database Protocol |
IIOP is Internet InterORB Protocol |
At the moment, the main focus in JavaBeans development is at the client side for GUI/widgets engineering |
However, the technology is applicable also at the server or middle tier (where JavaSoft calls it Enterprise JavaBeans and develops the specification) |
We are currently building new version of WebFlow that uses JavaBeans both for visual editing and for server-side ComponentWare |
5)Actual Data Transfer |
This involves sources, listeners and observers and is an interesting multi-tier model of linkage/communication |
One can (in some cases) merge observer and listener but not the listener and source |
Registration involves sending an object name -- termed the callback object -- from the listener to the source. |
When event occurs, the source invokes a particular (event dependent) method of the callback object |
Events can be distinguished by using different callback methods (demultiplexing) or by inspecting the argument of a more generic method. |
Sources and Listeners use a "controlled syntax" but there are no special interfaces or methods for linkage of observers and listeners as usually(often) these are combined. |
The various listeners and events are named in pairs XListener (an interface extending java.util.EventListener) and XEvent (an object extending java.util.EventObject) |
Registration involves methods for the source called
|
Such naming conventions are part of the design pattern for the JavaBean (JDK1.1) framework |
X = Component, Focus, Key, Mouse, MouseMotion, Window, Container, Text, Action, Adjustment and Item in JDK1.1 AWT |
Source of any class |
Listener implementing XListener |
Source contains method addXListener |
Source creates Event of type XEvent |
Listener contains a callback object with several methods each accepting argument of |
type XEvent |
Register |
callback |
object |
Invoke Callback |
Here we contrast the simple "A sends a message to B" model normally used in computing with the more general approach in the JavaBean Linkage model |
Define an event ADataReadyEvent with A as source and B as combined sink and listener |
A defines an instance Evtcontrol of ADataReadyEvent which has a method transferdata |
B instantiates an object Bcallback implementing interface ADataReadyListener with a method readytogo() |
B registers this listener object as a callback with A |
When A is ready to send data to B, A callbacks Bcallback.readtogo(ADataReadyEvent Evtcontrol) |
B calls back Evtcontrol.transferdata(sink information) |
Note that "control" mechanism uses powerful JavaBean approach (this is handshake) whereas one can use a totally different and faster approach to actually send data |
Traditional (in my world) mechanisms combine control and data transfer |