Title: Java Beans
1Java Beans
2What is a JavaBean?
3This is not a JavaBean!
4What is a JavaBean?
- A JavaBean is a reusable software component that
can be manipulated visually in a builder tool. - Example of builder tools NetBeans, IBM's Visual
Age, Borland/Inprise's JBuilder - The JavaBeans API provides a framework for
defining reusable, embeddable, modular software
components. - JavaBeans can take a variety of forms, from
invisible beans such as a timer to GUI components
such as a JComponent. - Although all beans can be manipulated visually,
this does not mean every bean has its own visual
representation. For example, javax.sql.RowSet is
a JavaBean component that represents the data
resulting from a database query.
5What is a JavaBean?
- There are no limits on the simplicity or
complexity of a JavaBeans component. - A complex system, such as an embeddable
spreadsheet application, can function as
individual JavaBean. - One of the goals of the JavaBeans model is
interoperability with similar component
frameworks. - The JavaBeans component model consists of the
java.beans and java.beans.beancontext packages
and a number of important naming and API
conventions to which conforming beans and
bean-manipulation tools must adhere. - See http//java.sun.com/beans/ for the JavaBeans
specification.
6Usage of JavaBeans
- JavaBeans
- Used for rapid application development
- Assembling predefined software components
- Programming in the large
- Used by a component assembler, such as NetBeans
- Promote code reuse
7- Ideally, we would like to build a substantial
application using prefabricated beans, without
ever writing a line of code! - Three characteristics of the JavaBeans
architecture make it possible to do that. - Design patterns (coding conventions)
- Reflection
- Object Serialization
8Design patterns
- Design patterns (i.e. coding conventions) let
tools and humans recognize the basic features of
a bean and manipulate it without knowing how it
is implemented. - By examining a Bean, we can tell what events it
can fire and receive we can learn about its
properties (the equivalent of its public
variables) and methods.
9Reflection
- Reflection makes it possible for Java program to
inspect and manipulate new Java objects at
runtime. - Reflection lets a beantool analyze a bean's
capabilities, examine the values of its fields,
and invoke its methods.
10Object Serialization
- The Java Serialization API allows us to "freeze"
a live application and revive it later. - This makes it possible to piece together
applications without extensive code generation. - Rather than customizing and compiling large
amounts of Java code to build an application on
startup, we can simply paste together beans,
configure them, tweak their appearance, and then
save them. Later, the beans can be restored with
all their state and interconnections intact. - This opens up a fundamentally different way of
thinking about the design process.
11NetBeans IDE
- In this course, we use the NetBeans IDE to
demonstrate and create beans. - NetBeans is a popular, pure Java development
environment for Java. - NetBeans offers powerful source-editor
capabilities, templates that aid in the creation
of various types of Java classes, and the ability
to compile, run, and debug applications, all in
one tool. - NetBeans is an open-source project with a modular
architecture that allows it to be easily extended
with new capabilities. - See http//www.netbeans.org
12Bean Characteristics
- Any object that conforms to certain basic rules
can be a bean there is no Bean class all beans
are required to subclass. - Many beans are AWT components, but it is also
quite possible and useful, to write "invisible"
beans that do not have an onscreen appearance. - A bean is characterized by the properties,
events, and methods it exports. - A property is a piece of the bean's internal
state that can be programmatically set and/or
queried through a standard pair of set and get
methods.
13Bean Characteristics (cont.)
- A bean communicates with the application in which
it is embedded and with other beans by generating
events. - The JavaBeans API uses the same event model AWT
and Swing components use. This model is based on
the java.util.EventObject class and the
java.util.EventListener interface. - The methods exported by a bean are any public
methods defined by the bean, excluding those
methods that get and set property values and
register and remove event listeners.
14Bean Event Model
- A bean defines an event if it provides add and
remove methods for registering and deregistering
listener objects for that event. - An application that wants to be notified when an
event of that type occurs uses these methods to
register an event listener object of the
appropriate type. - When the event occurs, the bean notifies all
registered listeners by passing an event object
that describes the event to a method defined by
the event listener interface.
15Specialized Properties
- In addition to the regular properties described
earlier, the JavaBeans API also supports indexed
property, bound property, and constrained
property. - An indexed property is a property that has an
array value, as well as getter and setter methods
that access both individual elements of the array
and the entire array. - A bound property is a property that sends a
PropertyChangeEvent to any interested
PropertyChangeListener objects whenever the value
of the property changes.
16- A constrained property is a property that can
have any changes vetoed by any interested
listener. - When the value of a constrained property of a
bean changes, the bean must send out a
PropertyChangeEvent to the list of interested
VetoableChangeListener objects. If any of these
objects throws a PropertyVetoException, the
property value is not changed, and the
PropertyVetoException is propagated back to the
property setter method.
17JavaBeans Conventions
- The JavaBeans component model relies on a number
of rules and conventions that bean-developers
must follow. - These conventions are referred to as design
patterns. They specify such things as method
names and signatures for property accessor
methods defined by a bean. - The reason for these design patterns is
interoperability between beans and the beantool
programs that manipulate them. - One such convention, for example, is that the
getter and setter methods for a property should
begin with get and set.
18JavaBeans Conventions Beans
- A bean itself must adhere to the following
conventions - Class name There are no restrictions on the
class name of a bean. - Superclass A bean can extend any other class.
Beans are often AWT or Swing components, but
there are no restrictions. - Instantiation A bean must provide a no-parameter
constructor or a file that contains a serialized
instance, so a beantool can instantiate the bean.
The file that contains the bean should have the
same name as the bean, with an extension .ser. - Bean name The name of a bean is the name of the
class that implements it or the name of the file
that holds the serialized instance of the bean.
19JavaBeans Conventions Properties
- A bean defines a property p of type T if it has
accessor - methods that follow these patterns (if T is
boolean, a special - form of getter method is allowed)
- Getter public T getP( )
- Boolean getter public boolean isP( )
- Setter public void setP(T)
- Exceptions Property accessor methods can throw
any type of checked or unchecked exceptions.
20JavaBeans Conventions Indexed Properties
- A bean defines an indexed property p of type T
if it defines - the following accessor methods
- Array getter public T getP( )
- Element getter public T getP(int)
- Array setter public void setP(T)
- Element setter public void setP(int,T)
- Exceptions Indexed property accessor methods can
throw any type of checked or unchecked
exceptions. In particular, they should throw an
ArrayIndexOutOfBoundsException if the supplied
index is out of bounds.
21JavaBeans Conventions Bound Properties
- Here are the conventions for a bound property
- Accessor methods follow the same conventions as
a regualr property. - Introspection A beantool cannot distinguish a
bound property from a nonbound property through
introspection alone. Therefore, we should
implement a BeanInfo class that returns a
PropertyDescriptor object for the property. The
isBound( ) method of this PropertyDescriptor
should return true. - Listener registration A bean that defines one or
more bound properties must define a pair of
methods for the registration of listeners that
are notified when any bound property value
changes. The methods must have these signatures
22JavaBeans Conventions Bound Properties (cont.)
- public void addPropertyChangeListener(
- PropertyChangeListener)
- public void removePropertyChangeListener(
- PropertyChangeListener)
- Named property listener registration A bean can
optionally provide additional methods that allow
event listeners to be registered for changes to a
single bound property value. These methods are
passed the name of a property and have the
following signatures - public void addPropertyChangeListener(
- String, PropertyChangeListener)
- public void removePropertyChangeListener(
- String, PropertyChangeListener)
23JavaBeans Conventions Bound Properties (cont.)
- Per-property listener registration A bean can
optionally provide additional event listener
registration methods that are specific to a
single property. For a property p, these methods
have the following signatures - public void addPListener( PropertyChangeListe
ner) - public void removePListener(
PropertyChangeListener) - Methods of this type allow a beantool to
distinguish a bound property from a nonbound
property. - Notification When the value of a bound property
changes, the bean should update its internal
state to reflect the change and then pass a
PropertyChangeEvent to the propertyChange()
method of every PropertyChangeListener object
registered for the bean or the specific bound
property. - Support java.beans.PropertyChangeSupport is a
helpful class for implementing bound properties.
24JavaBeans Conventions Constrained Properties
- Getter The getter method for a constrained
property is the same as the getter method for a
regular property. - Setter The setter method of a constrained
property throws a PropertyVetoException if the
property change is vetoed. For a property p of
type T, the signature looks like this - public void setP(T) throws
PropertyVetoException - Listener registration A bean that defines one or
more constrained properties must define a pair of
methods for the registration of listeners that
are notified when any constrained property value
changes. The methods must have these signatures - public void addVetoableChangeListener(
- VetoableChangeListener)
- public void removeVetoableChangeListener(
- VetoableChangeListener)
25JavaBeans Conventions Constrained Properties
(cont.)
- Named property listener registration A bean can
optionally provide additional methods that allow
event listeners to be registered for changes to a
single constrained property value. These methods
are passed the name of a property and have the
following signatures - public void addVetoableChangeListener(
- String, VetoableChangeListener)
- public void removeVetoableChangeListener(
- String, VetoableChangeListener)
- Per-property listener registration A bean can
optionally provide additional event listener
registration methods that are specific to a
single property. For a property p, these methods
have the following signatures - public void addPListener( VetoableChangeListe
ner) - public void removePListener(
VetoableChangeListener)
26JavaBeans Conventions Constrained Properties
(cont.)
- Notification When the value of a constrained
property changes, the bean should generate a
PropertyChangeEvent that describes the requested
change and pass the event to the vetoableChange()
method of every VetoableChangeListener object
registered for the bean or the specific
constrained property. If any listener vetoes the
change by throwing a PropertyVetoException, the
bean must send out another PropertyChangeEvent to
revert the property to its original value, and
then it should throw a PropertyVetoException
itself. If, on the other hand, the property
change is not vetoed, the bean should update its
internal state to reflect the change. If the
constrained property is also a bound property,
the bean should notify PropertyChangeListener
objects at this point. - Support java.beans.VetoableChangeSupport is a
helpful class for implementing constrained
properties.
27JavaBeans Conventions Events
- In addition to PropertyChangeEvent events
generated when bound - and constrained properties are changed, a bean
can generate other - types of events. An event named E should follow
these conventions - Event class The event class should directly or
indirectly extend java.util.EventObject and
should be named EEvent. - Listener interface The event must be associated
with an event listener interface that extends
java.util.EventListener and is named EListener. - Listener methods The event listener interface
can define any number of methods that take a
single argument of type EEvent and return void.
28JavaBeans Conventions Events (cont.)
- Listener registration The bean must define a
pair of methods for registering event listeners
that want to be notified when an E event occurs.
The methods should have the following signatures - public void addEListener(EListener)
- public void removeEListener(EListener)
- Unicast events A unicast event allows only one
listener object to be registered at a single
time. If E is a unicast event, the listener
registration method should have the signature - public void addEListener(EListener) throws
- TooManyListenersException
29JavaBeans Conventions Methods
- A beantool can expose the methods of a bean to
application - designers. The only formal convention is that
these methods must be - declared public. The following guidelines are
also useful - Method name A method can have any name that does
not conflict with the property and event names. - Parameters A method can have any number and type
of parameters. - Excluding methods A bean can explicitly specify
the list of methods it exports by providing a
BeanInfo implementation. - Documentation A bean can provide user-friendly,
human-readable localized names and descriptions
for methods through MethodDescriptor objects
returned by a BeanInfo implementation.
30JavaBeans Conventions Auxiliary Classes
- A bean can provide the following auxiliary
classes - BeanInfo To provide additional information about
a bean B, implement the BeanInfo interface in a
class named BBeanInfo. - Property editor for a specific type To enable a
beantool to work with properties of type T,
implement the PropertyEditor interface in a class
named TEditor. The class must have a no-parameter
constructor. - Property editor for a specific property To
customize the way a beantool allows the user to
enter the values for a single property,define a
class that implements the PropertyEditor
interface and has a no-parameter constructor, and
register that class with a PropertyDescriptor
object returned by the BeanInfo class for the
bean.
31JavaBeans Conventions Auxiliary Classes (cont.)
- Customizers To define a customizer, or wizard,
for configuring a bean B, define an AWT or Swing
component with a no-parameter constructor that
does the customization. The class is commonly
named BCustomizer. Register the class with the
BeanDescriptor object returned by the BeanInfo
class for the bean. - Documentation Define default documentation for a
bean B in HTML format and store that
documentation in a file named B.html.
32JavaBeans Conventions Bean Packaging
- Beans are distributed in JAR archive files that
have the following - format
- Content The class or classes that implement a
bean should be included in the JAR file, along
with auxiliary classes such as BeanInfo and
PropertyEditor implementations. If the bean is
instantiated from a serialized instance, that
instance should be included in the JAR archive
with a filename ending in .ser. The JAR file can
contain HTML documentation for the bean and
should also contain any resource files, such as
images, required by the bean and its auxiliary
classes. A single JAR file can contain more than
one bean. Within a JAR file, / is always used as
the directory separator. - Java-Bean attribute The manifest of the JAR file
must mark any .class and .ser files that define a
bean with the attribute - Java-Bean True
33trivial beans
- The following class is a Bean, albeit an
invisible and useless one - public class Trivial
- implements java.io.Serializable
- It doesn't have any properties, and it doesn't do
anything. But it's a Bean nonetheless, and we can
drag it into NetBeans/BDK. - If we modify this class to extend
javax.swing.JComponent, we suddenly have a
graphical Bean, with lots of standard Swing
properties, such as size and color - public class TrivialComponent
- extends javax.swing.JComponent
34The Dial Bean
35File beans/Dial.java
- package beans
- import java.awt.
- import java.awt.event.
- import java.util.
- import javax.swing.
- public class Dial extends JComponent
- //instance variables
- int minValue, nvalue, maxValue, radius
- //constructors
- public Dial()
- this(0, 100, 0)
-
36- public Dial(int minValue, int maxValue, int
value) - setMinimum( minValue )
- setMaximum( maxValue )
- setValue( value )
- setForeground( Color.orange )
- addMouseListener(new MouseAdapter()
- public void mousePressed(MouseEvent e)
spin(e) - )
- addMouseMotionListener(new MouseMotionAdapter(
) - public void mouseDragged(MouseEvent e)
spin(e) - )
-
-
37- protected void spin( MouseEvent e )
- int y e.getY()
- int x e.getX()
- double th Math.atan((1.0 y - radius) / (x
- radius)) - int value(int)(th / (2 Math.PI)
(maxValue - minValue)) - if (x lt radius)
- setValue( value (maxValue-minValue) / 2
minValue) - else if (y lt radius)
- setValue( value maxValue )
- else
- setValue( value minValue)
-
-
38- public void paintComponent(Graphics g)
- Graphics2D g2 (Graphics2D)g
- int tick 10
- radius Math.min( getSize().width,getSize().h
eight )/2 - tick - g2.setPaint( getForeground().darker() )
- g2.drawLine( radius 2 tick / 2, radius,
- radius 2 tick, radius)
- g2.setStroke( new BasicStroke(2) )
- draw3DCircle( g2, 0, 0, radius, true )
- int knobRadius radius / 7
- double th nvalue (2 Math.PI) /
(maxValue - minValue) - int x (int)(Math.cos(th) (radius -
knobRadius 3)) - int y (int)(Math.sin(th) (radius -
knobRadius 3)) - g2.setStroke(new BasicStroke(1))
- draw3DCircle(g2, x radius - knobRadius,
- y radius - knobRadius, knobRadius, false
) -
-
39- private void draw3DCircle(
- Graphics g, int x, int y, int radius,
boolean raised) - Color foreground getForeground()
- Color light foreground.brighter()
- Color dark foreground.darker()
- g.setColor(foreground)
- g.fillOval(x, y, radius 2, radius 2)
- g.setColor(raised ? light dark)
- g.drawArc(x, y, radius 2, radius 2, 45,
180) - g.setColor(raised ? dark light)
- g.drawArc(x, y, radius 2, radius 2, 225,
180) -
- public Dimension getPreferredSize()
- return new Dimension(100, 100)
-
- public void setValue( int value )
- this.nvalue value - minValue
- repaint()
- fireEvent()
40- public int getValue() return
nvalueminValue - public void setMinimum(int minValue)
this.minValue minValue - public int getMinimum() return minValue
- public void setMaximum(int maxValue)
this.maxValue maxValue - public int getMaximum() return maxValue
- //the variable listenerList is inherited from
JComponent - public void addDialListener(DialListener
listener) - listenerList.add( DialListener.class,
listener ) -
- public void removeDialListener(DialListener
listener) - listenerList.remove( DialListener.class,
listener ) -
- void fireEvent()
- Object listeners listenerList.getListenerL
ist() - for ( int i 0 i lt listeners.length i 2
) - if ( listenersi DialListener.class )
- ((DialListener)listenersi
1).dialAdjusted( - new DialEvent(this, getValue()) )
-
41- public static void main(String args)
- JFrame frame new JFrame("DialBean")
- final JLabel statusLabel new
JLabel("Welcome to DialBean") - final Dial dial new Dial()
- frame.getContentPane().add(dial,
BorderLayout.CENTER) - frame.getContentPane().add(statusLabel,
BorderLayout.SOUTH) - dial.addDialListener(new DialListener()
- public void dialAdjusted(DialEvent e)
- statusLabel.setText("Value is "
e.getValue()) -
- )
- frame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE ) - frame.setSize( 150, 150 )
- frame.setVisible( true )
-
-
42File beans/DialListener.java
- package beans
- public interface DialListener extends
- java.util.EventListener
- void dialAdjusted( DialEvent e )
-
43File beans/DialEvent.java
- package beans
- public class DialEvent extends
- java.util.EventObject
- int value
- DialEvent( Dial source, int value )
- super( source )
- this.value value
-
- public int getValue()
- return value
-
44Customizing with BeanInfo
- The java.beans.Introspector class gathers
information on a bean using reflection, then
analyzes and describes the bean to any tool that
wants to know about it. - The introspection process works only if the class
follows the JavaBeans naming conventions. It
gives us little control over exactly what
properties and events appear in NetBeans menus. - For example, by default, NetBeans shows all the
stuff inherited from the base Swing component. - We can change that by creating BeanInfo classes
for our beans. - A BeanInfo class provides the JavaBeans
introspector with explicit information about the
properties, methods, and events of a bean.
45Customizing with BeanInfo (cont.)
- A BeanInfo class implements the BeanInfo
interface. - But for simplicity, we can extend the
SimpleBeanInfo class, which implements all
BeanInfo's methods. We can override specific
methods to provide the information we want. When
we don't override a method, we'll get the
introspector's default behavior. - As an example, we'll develop a DialBeanInfo class
that provides explicit information about our Dial
bean.
46Getting Properties Information
- To describe the Dial's properties, we must
implement the getPropertyDescriptors() method. - This method simply returns an array of
PropertyDescriptor objects, one for each property
we want to publicize. - To create a PropertyDescriptor, call its
constructor with two arguments the property's
name and the class. - A useful thing about DialBeanInfo is that by
providing explicit information for our
properties, we automatically hide other
properties that introspection might find.
47Getting Events Information
- The Dial bean defines its own event the
DialEvent. - We want to tell development tools about this
event so that we can build applications using it. - We add a method to the DialBeanInfo class called
getEventSetDescriptors(), which returns an array
of EventSetDescriptors. - Events are described in terms of their listener
interfaces, not in terms of the event classes
themselves. - We create an EventSetDescriptor object dial. The
constructor takes four arguments the class that
generates the event, the name of the event, the
listener class, and the name of the method to
which the event can be delivered.
48Supplying Icons
- In order to make NetBeans display our bean on the
palette with a cute icon, we supply an icon by
having the BeanInfo class implement the
getIcon() method. - We may supply up to four icons, with sizes of
16x16 or 32x32, in either color or monochrome.
49File beans/DialBeanInfo.java
- package beans
- import java.beans.
- public class DialBeanInfo extends SimpleBeanInfo
- public PropertyDescriptor getPropertyDescripto
rs() - try
- PropertyDescriptor value
- new PropertyDescriptor("value",
Dial.class) - PropertyDescriptor minimum
- new PropertyDescriptor("minimum",
Dial.class) - PropertyDescriptor maximum
- new PropertyDescriptor("maximum",
Dial.class) - value.setBound(true)
- minimum.setBound(false)
- maximum.setBound(false)
- return new PropertyDescriptor value,
minimum, maximum - catch (IntrospectionException e) return
null -
50- public EventSetDescriptor getEventSetDescripto
rs() - try
- EventSetDescriptor dial new
EventSetDescriptor( Dial.class, - "dialAdjusted", DialListener.class,
"dialAdjusted") - dial.setDisplayName("Dial Adjusted")
- EventSetDescriptor changed new
EventSetDescriptor( - Dial.class, "propertyChange",
- PropertyChangeListener.class,
"propertyChange" ) - changed.setDisplayName("Bound property
change") -
- return new EventSetDescriptor dial,
changed - catch (IntrospectionException e) return
null -
-
51-
- public java.awt.Image getIcon(int iconKind)
- if (iconKind BeanInfo.ICON_COLOR_16x16)
- return loadImage("DialIconColor16.gif"
) - else
- if (iconKind BeanInfo.ICON_COLOR_32x32)
- return loadImage("DialIconColor32.gif"
) - else
- if (iconKind BeanInfo.ICON_MONO_16x16)
- return loadImage("DialIconMono16.gif")
- else
- if (iconKind BeanInfo.ICON_MONO_32x32)
- return loadImage("DialIconMono32.gif")
-
- return null
-
- //end class DialBeanInfo