Design time information
Exceptions while executing handlers
Custom property editors and customizers
How custom Beans are stored
In addition to the build-in Swing components (which are also Beans), you can import custom Beans from JAR archives. A Bean must fulfill these minimum requirements so it can be imported:
Importing Beans Top of page
Select 'File | Import Beans' and, from the file dialog, select
Tutorial/Examples/customcomponents.jar. The 'Import Beans' dialog opens where you choose which Beans to import.
If you encounter
NoClassDefFoundErrors when trying to import Beans, read the next section about specifying libraries.
Specifying libraries Top of page
Choose 'File | Libraries...' to open the 'Libraries' dialog. Libraries defined here are intended for resolving dependencies of imported Beans (typical candidates might be
infobus.jar). Libraries may be either
The BeanContext Top of page
RADi provides one
BeanContextServices implementation per layout. Beans implementing either
BeanContextProxy are automatically added to the bean context. Service providing Beans are responsible for registering their service(s) with the context.
BeanContext is valid only while the test frame is displayed and will be cleared when the test frame is closed.
By choosing 'Layout | BeanContext Info...' you see an overview on the bean context's nested children and registered services.
Design time information Top of page
BeanContext aware Beans can get design time information from the enclosing bean context by calling
getBeanContext().isDesignTime(), other Beans may call
java.beans.Beans.isDesignTime(). While no test frame is displayed, both methods will return
true, else both methods will return
Non-component Beans Top of page
Non-component Beans are generally not derived from
java.awt.Component and encapsulate some application logic. Though non-component Beans have a visual representation inside RADi, you cannot add them to the GUI and they are not visible in a running application.
If you are a Bean developer and your Bean is derived from
java.awt.Component but, for some reason, you want it to be treated as non-component Bean, you can achieve this by implementing
java.beans.Visibility and let the implementation return
Using Beans Top of page
The 'Beans' button in the component palette has a popup menu attached from which you select Beans.
Inserting Beans is different for component Beans and non-component Beans. To insert a component Bean into the design grid, you drag the icon to a grid cell, just like you do with any other component. To insert a non-component Bean, just click the 'Custom Beans' button. The Bean will be added to the 'Non-Component Beans' panel which is initially invisible.
From the context menu of a custom Bean you can open the 'Custom Bean Info' dialog which displays the path to the imported JAR. If the JAR is not inside the project directory, you will see a warning.
Event propagation Top of page
Event propagation allows for simple inter-Bean communication. You have to specify an event source and one or more event targets. As the specified listener method is called on the event source, the specified method of the event target will be executed.
As a simple example we will setup a list and a text field such that the text field displays the list's selected value.
To do this programatically you would have to code:
We start by selecting 'Propagate Event...' from the list's context menu. The 'Select Event Source' dialog opens.
Because we want to react to changes in the list selection, we select the
listSelection item from the 'Select listener' combo box. A
ListSelectionListener has only one method, so the selected listener method is okay.
In the first table, the
ListSelectionEvent's properties are displayed. Click inside the 'source' row.
Though the event's "source" property has a return type of
Object, RADi knows that the event source is the list, so the second table displays all of an
AList's (non-deprecated) public methods which have a non-void return type and take no arguments. Scroll to the 'getSelectedValue()' row and select it.
getSelectedValue() has a return type of
Object, so the third table now displays public
Object methods. Search for the 'toString()' row and click choose.
Specifying the event source was the hard part, now we will define the event target (method).
Right-click the text field and select 'Event Target...' from its context menu.
String. Because we want to display the selected item as the text field's text, we choose
setText(String). To test the new event handler, display a test frame and select items from the list.
Property propagation Top of page
Property propagation describes two slightly different mechanisms:
To specify the property source, choose 'Propagate Property' from a component's/Bean's context menu. From the 'Select Property Source' dialog you select a property. All properties whose getter method takes no arguments are listed.
In the next step you specify a property target and a target method. The type of the property and the parameter type of the method must match.
The 'Edit Property Handler' dialog allows to remove entries and to change target methods.
Exceptions while executing handlers Top of page
Both event handlers and property handlers might raise exceptions as they are executed.
With property handlers you will see an exception dialog as soon as you have defined the handler.
with the label's border being
null (just to demonstrate how easy it is, to force exceptions).
With event handlers, an exception might be thrown as you trigger the event.
Because the argument is a component which is not a child of the tabbed pane, the tabbed pane throws
java.lang.IllegalArgumentException: component not found in tabbed pane (wrapped in an
InvocationTargetException because RADi executed a reflective call).
There's nothing more you can do but remove the handler in question.
Custom property editors and customizers Top of page
If a custom Bean's
BeanInfo specifies any custom property editors (with
PropertyDescriptor.setPropertyEditorClass(Class)), RADi instantiates the editor class and attaches the editor to the specified property. The custom editor will be displayed in a modal dialog, together with a "Close" button.
BeanDescriptor specifies a
Customizer, the first row of the property sheet shows the customizer class and a "Customize..." label. Clicking the label will open the Customizer dialog, displaying the customizer component and a "Close" button.
How custom Beans are stored Top of page
RADi stores a Bean's state by storing all the public properties which a user (you) has edited. If a property is of known type
KeyStroke), it will be stored in a RADi-special format, else it will be stored using
XMLEncoder. If this fails (for example because the property type provides no default constructor) and the property class implements
Serializable, it will be stored using object serialization.
If a Bean's state depends on non-public properties, it must provide a
BeanInfo class and either
Provided Beans Top of page