SoFunction
Updated on 2025-04-06

JavaBeans Program Development

Properties of JavaBeans

The properties of JavaBeans are the same as the properties referred to in general Java programs, or the properties of objects in all object-oriented programming languages. The specific manifestation in the program is the variables in the class. In JavaBeans design, it is divided into four categories according to the different functions of attributes: Simple, Index, Bound and Constrained attributes.

 1. Simple attributes

A simple property represents a variable accompanied by a pair of get/set methods (a procedure or function in C language is called "methods" in Java programs). The attribute name corresponds to the get/set method name associated with the attribute. For example: If there are setX and getX methods, it implies that there is a property named "X". If there is a method named isX, it is usually implied that "X" is a Boolean property (i.e., the value of X is true or false). For example in the following program:

public class alden1 extends Canvas {
string ourString= "Hello"; //The property is called ourString, type is a string
public alden1(){ //alden1() is the constructor of alden1,
The same meaning as the constructor in C++
setBackground();
setForeground();
}
/* "set" attribute*/
public void setString(String newString) {
ourString=newString;
}
/* "get" attribute */
public String getString() {
return ourString;
}
}

2. Indexed attributes

An Indexed property represents an array value. Use the set/get method corresponding to this property to obtain the numerical value in the array. This property can also set or obtain the value of the entire array at once. example:

public class alden2 extends Canvas {
int[] dataSet={1,2,3,4,5,6}; // dataSet is an indexed property
public alden2() {
setBackground();
setForeground();
}
/* Set the entire array */
public void setDataSet(int[] x){
dataSet=x;
}
/* Sets the value of a single element in the array */
public void setDataSet(int index, int x){
dataSet[index]=x;
}
/* Get the entire array value */
public int[] getDataSet(){
return dataSet;
}
/* Get the specified element value in the array */
public int getDataSet(int x){
return dataSet[x];
}
}

3. Bound attribute

A Bound attribute refers to notifying other objects when the value of this attribute changes. Each time the property value changes, this property ignites a PropertyChange event (in Java programs, the event is also an object). The event encapsulates the attribute name, the original value of the attribute, and the new value after the property changes. This kind of event is passed to other beans, and the actions that the beans receiving the event should be defined by itself. When the background property of PushButton is bound to the background property of Dialog, if the background property of PushButton changes, the background property of Dialog also changes. example:

public class alden3 extends Canvas{
String ourString= "Hello";
//ourString is a bound property
private PropertyChangeSupport changes = new PropertyChangeSupport(this);
/** Note: Java is a pure object-oriented language.
If you want to use a method, you must specify which object method to use.
In the following program, the ignition event operation is to be performed.
The method used for this operation is in the PropertyChangeSupport class.
So the above declares and instantiates a changes object,
The following will use the firePropertyChange method of changes to ignite the property of ourString change event. */

public void setString(string newString){
String oldString = ourString;
ourString = newString;
/* The property value of ourString has changed, so the ignition property changes event */
("ourString",oldString,newString);
}
public String getString(){
return ourString;
}
/** The following code is used for development tools.
We cannot predict which other beans alden3 will combine into an application.
It is impossible to predict what other components will be related to this change if the ourString property of alden3 changes.
Therefore, alden3 Beans needs to reserve some interfaces for development tools.
Development tools use these interfaces,
Mount other JavaBeans objects with alden3. */

public void addPropertyChangeListener(PropertyChangeLisener l){
(l);
}
public void removePropertyChangeListener(PropertyChangeListener l){
(l);
}

Through the above code, the development tool calls the addPropertyChangeListener method of changes, registers other JavaBeans into the listener queue l of ourString property. l is a Vector array that can store any Java objects.

The development tool can also use the removePropertyChangeListener method of changes to log out the specified object from l, so that the change of the ourString property of alden3 is no longer related to this object.

Of course, when programmers write code to compile programs by hand, they can also directly call these two methods to mount other Java objects with alden3.

4. Constrained properties

    A JavaBeans constrained property refers to the change of the property value of other Java objects that have established some connection with this property when the value of this property is about to change. The listener of the constrained property prevents the change of the property value by throwing a PropertyVetoException. Example: The constrained property in the following program is PriceInCents.

public class JellyBeans extends Canvas{
private PropertyChangeSupport changes=new PropertyChangeSupport(this);
private VetoableChangeSupport Vetos=new VetoableChangeSupport(this);
/*Same as the aforementioned changes,
Methods in Vetos can be used in instances of VetoableChangeSupport object,
Prevent the change of PriceInCents value under specific conditions. */
......
public void setPriceInCents(int newPriceInCents) throws PropertyVetoException {
/*The function of throws PropertyVetoException in the method name is when there is
When other Java objects reject changes in PriceInCents,
To throw exceptions. */
/* Save the original attribute value first*/

int oldPriceInCents=ourPriceInCents;
/**Ignition property changes veto event*/
("priceInCents",new Integer(OldPriceInCents),new Integer(newPriceInCents));

/**If other objects reject the change of priceInCents,
The program throws an exception and no longer continues to execute the following two statements.
The method ends. If no other object rejects the change of priceInCents,
Then, in the following code, ourPriceIncents will be assigned a new value.
And ignition property change event*/

ourPriceInCents=newPriceInCents;
("priceInCents", new Integer(oldPriceInCents), new Integer(newPriceInCents));
}

/**Same as the aforementioned changes,
Also reserve interfaces for the PriceInCents property.
Make other objects register in PriceInCents veto change listener queue,
Or log out of the object

public void addVetoableChangeListener(VetoableChangeListener l)
{
(l);
}
public void removeVetoableChangeListener(VetoableChangeListener l){
(l);
}
......
}

As can be seen from the example above, a constrained property has two types of listeners: the attribute change listener and the listener who rejects the attribute change. The listener who rejects the change of attributes has corresponding control statements in his object code. When listening to a constrained attribute change, he will determine whether the change of the attribute value should be rejected in the control statement.

In short, whether the value of a constrained property of a beans can be changed depends on whether other beans or Java objects allow such changes. The conditions for permission or not are defined by other Beans or Java objects in their own class.

JavaBeans events

Event processing is one of the core of the JavaBeans architecture. Through the event processing mechanism, some components can be used as the event source to emit events that can be received by the description environment or other components. In this way, different components can be combined in the construction tool, and the components communicate through the transmission of events to form an application. Conceptually speaking, events are a mechanism for transferring a certain state change between the "source object" and the "listener object". Events have many different uses, such as mouse events, window boundary changes, keyboard events, etc. that are often processed in Windows systems. In Java and JavaBeans, a general, extensible event mechanism is defined, which can:

· Provides a public framework for the definition and expansion of event types and models of delivery and is suitable for a wide range of applications.

·High integration with Java language and environment.

· Events can be captured and ignited by the description environment.

·Can enable other constructors to adopt some technology to directly control events and the connection between event sources and event listeners at design time.

·The event mechanism itself does not rely on complex development tools. In particular, it should also be:

·Able to discover events that can be generated by the specified object class.

·Able to discover events that can be observed (listened) by the specified object class.

Provides a conventional registration mechanism that allows dynamic manipulation of the relationship between the event source and the event listener.

·No other virtual machines or languages ​​are required to implement it.

·Efficient event delivery can be carried out between the event source and the listener.

·Able to complete the neutral mapping of JavaBeans event model and related other component architecture event models.

The main components of the JavaBeans event model are: The passing of events from the event source to the listener is performed through Java method calls to the target listener object. For the occurrence of each explicit event, a clear Java method is defined accordingly. These methods are centrally defined in the EventListener interface, which must be inherited. The class that implements some or all methods in the event listener interface is the event listener. As events occur, the corresponding state is usually encapsulated in the event state object, which must be inherited from. The event status object is passed as a single parameter to the listener method that should respond to the event. The identity of the event source that issues a particular event is: defines the registration method for the event listener in accordance with the specified design format and accepts references to the specified event listener interface instance. Sometimes, when event listeners cannot directly implement the event listener interface, or there are other additional actions, they need to insert an instance of the event adapter class between one source and one or more listeners to establish a connection between them.

Event State Object

State information related to event occurrence is generally encapsulated in an event state object, which is a subclass of the object. According to design practice, the name of this event state object class should end with Event. For example:

public class MouseMovedExampleEvent extends
{
protected int x, y;
/* Create a mouse movement event MouseMovedExampleEvent */
MouseMovedExampleEvent( source, Point location) {
super(source);
x = ;
y = ;
}
/* Get the mouse position*/
public Point getLocation() {
return new Point(x, y);
}
}

EventListener Interface and Event Listener

Since the Java event model is based on method calls, a way to define and organize event manipulation methods is required. In JavaBeans, event manipulation methods are defined in the EventListener interface that inherits the class. According to regulations, the naming of the EventListener interface must end with a Listener. Any class that wants to manipulate the methods defined in the EventListener interface must be performed in the implementation of this interface. This class is the event listener. For example:

/*A mouse movement event object was defined first*/
public class MouseMovedExampleEvent
extends {
// This class contains status information related to mouse movement events
...
}
/*Define the listener interface for mouse movement events*/
interface MouseMovedExampleListener
extends {
/*Define the method that the mouse movement event listener should support in this interface*/
void mouseMoved(MouseMovedExampleEvent mme);
}

Only the method name, method parameters and return value types are defined in the interface. For example: the specific implementation of the mouseMoved method in the above interface is defined in the ArbitraryObject class below.

class ArbitraryObject implements MouseMovedExampleListener {
public void mouseMoved(MouseMovedExampleEvent mme)
{ ... }
}

ArbitraryObject is the listener of the MouseMovedExampleEvent event.

Registration and cancellation of event listeners

In order for various possible event listeners to register themselves into the appropriate event source and establish an event flow between the source and the event listener, the event source must provide the event listener with a method of registration and cancellation. This usage process has been seen in the previous introduction to the bound attribute. In practice, the registration and cancellation of event listeners must be used in a standard design format:

public void add< ListenerType>(< ListenerType> listener);
public void remove< ListenerType>(< ListenerType> listener);

For example:

First, an event listener interface is defined:

public interface
ModelChangedListener extends {
void modelChanged(EventObject e);
}

Next define the event source class:

public abstract class Model {
private Vector listeners = new Vector(); // Define an array that stores event listeners

/*The <ListenerType> in the above design format is here the ModelChangedListener below*/

public synchronized void addModelChangedListener(ModelChangedListener mcl)
{ (mcl); }//Register the listener into the listeners array
public synchronized void removeModelChangedListener(ModelChangedListener mcl)
{ (mcl); //Login the listener from listeners

/*The above two methods are synchronized.
Because when running in a multi-threaded environment,
There may be several objects that need to be registered and cancelled at the same time.
Use synchronized to ensure synchronization between them.
Developer tools or programmers use these two methods to build event flow between the source and the listener*/

protected void notifyModelChanged() {
/**Event source Use this method to notify the listener that the modelChanged event has occurred*/
  Vector l;
EventObject e = new EventObject(this);
/* First, copy the listener to the l array.
Freeze the state of EventListeners to pass events.
This ensures that the event is delivered to all events?
The corresponding method of the target listener who has received the event will not take effect. */
synchronized(this) {
l = (Vector)();
}
for (int i = 0; i < (); i++) {
/* Notify each listener registered in the listener queue that a modelChanged event occurred.
And pass the event state object e as a parameter to each listener in the listener queue*/
((ModelChangedListener)(i)).modelChanged(e);
}
  }
 }

In the program, the event source Model class explicitly calls the modelChanged method in the interface, and actually passes the event state object e as a parameter to the modelChanged method in the listener class.

Adaptation class

Adaptation classes are an extremely important part of the Java event model. In some application cases, the transfer of events from the source to the listener must be "forwarded" through the adapter class. For example: When an event source emits an event and several event listener objects can receive the event, but only when the specified object reacts, an event adapter class must be inserted between the event source and the event listener, and the adapter class specifies which listeners should respond to the event.

The adapter class becomes an event listener. The event source actually registers the adapter class as a listener and is in the listener queue. The real event responder is not in the listener queue. The actions that the event responder should do are determined by the adapter class. Currently, most development tools are processed through adaptive classes when generating code.

JavaBeans User

JavaBeans developers can add a customizer, property editor, and BeansInfo interface to a Beans to describe the content of a Beans. Beans users can use the information attached to the Beans in the construction environment to customize the appearance and actions of the Beans. A bean does not need to have BeansCustomizer, PrpertyEditor and BeansInfo. These are optional depending on the actual situation. When some beans are more complex, this information must be provided to enable beans users to personalize a bean in the form of Wizard. Some simple beans may not have any of these information, so the construction tool can use its own perspective device to see out the content of the beans and display the information in a standard attribute table or event table for users to customize the beans. The attributes, methods and event names of the beans mentioned in the previous sections must be named in a certain format. The main function is to enable the development tool to see through the beans. Of course, it also provides convenience for programmers to use Beans in handwritten programs, so that they can observe their name and know their meaning.

Customizer Interface

When a Beans has its own username, it can display its own attribute table in the construction tool. Interfaces must be implemented when defining usernames. For example, here is a customizer for "button" Beans:

public class OurButtonCustomizer
extends Panel implements Customizer {
... ...
/*When implementing a regular attribute table like OurButtonCustomizer,
Be sure to implement addProperChangeListener in it
and removePropertyChangeListener, so
The constructor uses these functional codes to add listeners to property events. */
... ...
private PropertyChangeSupport changes=new PropertyChangeSupport(this);
public void addPropertyChangeListener(PropertyChangeListener l) {
(l);
public void removePropertyChangeListener(PropertyChangeListener l) {
 (l);
}
... ...

PropertyEditor Interface

A JavaBeans can provide the PropertyEditor class to create an editor for the specified properties. This class must be inherited from the class. Programmers who construct tools and handwritten code do not use this class directly, but instantiate and call this class in BeansInfo in the next section. example:

public class MoleculeNameEditor extends {
public String[] getTags() {
String resule[]={
 "HyaluronicAcid","Benzene","buckmisterfullerine", "cyclohexane","ethane","water"};
return resule;}
}

In the above example, a property editor was created for the Tags attribute. In the construction tool, you can select the attribute of MoleculeName from the drop-down table to be "HyaluronicAid" or "water".

BeansInfo interface

Each Beans class may also have a BeansInfo class associated with it, where it describes how this beans will look when it appears within the constructor. BeansInfo can define properties, methods, and events, display their names, and provide simple help instructions. For example:

public class MoleculeBeansInfo extends SimpleBeansInfo {
public PropertyDescriptor[] getPropertyDescriptors() {
try {
 PropertyDescriptor pd=new PropertyDescriptor("moleculeName",);
/*Refer to the MoleculeNameEditor class in the previous section through pd, obtain and return the moleculeName property*/
 ();
 PropertyDescriptor result[]={pd};
 return result;
} catch(Exception ex) {
 ("MoleculeBeansInfo: unexpected exeption: "+ex);
 return null;
}
}
}

JavaBeans persistence

When a JavaBeans is user-made in the construction tool and connected to other beans, all its states should be saved. The next time it is loaded into the construction tool or run, it should be the information that was last modified. In order to do this, you must save the information of certain fields of Beans and enable it to implement the interface when defining Beans. For example:

public class Button
implements {}

The information of fields in Beans that implement the serialized interface will be automatically saved. If you do not want to save information about certain fields, you can prefix these fields with transient or static keywords. Information about transient and static variables cannot be saved. Generally, all publicly disclosed properties of a Bean should be saved, and the internal state can be optionally saved. When modifying software, Beans developers can add fields, remove references to other classes, and change the private/protected/public state of a field. These do not affect the class's storage structure relationship. However, when deleting a field from the class, changing the position of a variable in the class system, changing a field to transient/static, or it was originally transient/static, and now it is changed to another feature, it will cause changes in the storage relationship.

JavaBeans storage format

After the JavaBeans component is designed, it is generally stored in a Zip format file with the extension jar, which contains information related to JavaBeans in the jar, and uses the MANIFEST file to specify which of the classes are JavaBeans. When JavaBeans stored in jar files are transmitted on the network, the number of data transmission is greatly reduced, and some resources required for JavaBeans runtime are bundled together. This chapter mainly discusses some internal features of JavaBeans and their conventional design methods, and refers to the JavaBeans specification version 1.0A. As major ISVs around the world support JavaBeans more and more, the specifications are still evolving in some details, but the basic framework will not change significantly.