R-Beans  (RADi Beans)

  How to create an R-Bean
  Propagating properties of nested components
  Using R-Beans
  R-Beans and Internationalization
  R-Bean FAQs

An R-Bean is some visual entity (either a single component, a composition of components or a containment hierarchy), supposed to appear in several layouts of a project.

Every R-Bean starts as an ordinary layout, then you convert this layout into an R-Bean (the layout is exported and compiled and its "R-Bean" flag is set). You can then insert instances of the R-Bean in other layouts of the current project, just as you do with imported Beans. (From the target layout's point of view, the R-Bean is just an instance of a Java class, this is why R-Beans must be compiled).

Advantages of R-Beans are that changes on an R-Bean are performed in one central place (the R-Bean layout) and are immediately reflected in all instances. To make R-Beans more useful, RADi allows to extend their public interface with new properties in two ways: Either propagate some property of a nested component to the outside world or specify a completely new property.

Note: There is one special case when you shouldn't make a layout an R-Bean. This is when a layout contains a JavaBean which loads a native library. Then, when instantiating the R-Bean, you might see an exception saying: java.lang.UnsatisfiedLinkError: Native Library [some_library_name] already loaded in another classloader. (You will see the exception only if the Bean prints a stacktrace or some other message. What exactly happens if the library can not be loaded depends on the Beans internal implementation).


How to create an R-Bean     Top of page

Any layout can be converted to an R-Bean (this implies that an R-Bean can contain both JavaBeans and other R-Beans).

Imagine a help button: A button with an icon, the label "Help" and a setHelpID(String) method, supposed to appear in most dialogs of your application (see the example layout '34 RBean HelpButton').
To implement the help button as an R-Bean, follow these steps:
Create a new layout.
Insert a JButton in a grid cell of your choice.
Set an icon for the button and set the button's text to "Help".
Select 'Layout | Convert to R-Bean'.
Enter a package name and a class name, then press [Export-Compile] and last [Convert].

Note: At 'File | Preferences | Compiler' you can set some compiler options. By default, javac will create 1.4 compatible class files and add debug information for line numbers and source file names.
The exported class extends AButton (RADi's variant of JButton), the class code is really simple (comments omitted):

Just like a JavaBean, an R-Bean must have a default (no argument) constructor. The call to RadiLoader.loadObjects(...) loads and processes the layout definition file (set the button's icon and text).
To extend the public interface with a helpID property, select 'Layout | Edit R-Bean'.
Choose String as the property type and enter "helpID" as the property name, then click [Add] (the default value will be an empty string, that's ok).

After creating an instance of HelpButton, the new property will appear in the property sheet.
You will be prompted to export and compile the R-Bean, here is the resulting code (comments omitted):

The code generator created a member field for the property as well as getter and setter methods. The property is bound, this means that a PropertyChangeEvent is fired as the property is changed. Note that the helpID field has private access, so it can only be changed through the setter method. Getters and setters are always public, independently of the export settings.
Finally you should register an ActionListener on the button and execute some code as the button is pressed. The exported and edited listener method might look similar to this one:


Propagating properties of nested components     Top of page

With R-Beans composed of several components you may have the need to access some property of a nested component through the R-Bean class. Defining such a property wrapper is simple. I illustrate this on the example R-Bean "36 RBean InfoPanel" which consists of two labels, one displaying an icon and one responsible for displaying the info text.

Select 'Layout | Edit R-Bean' to display the 'Edit R-Bean' dialog.

Select the nested component as the property Target (label1).
Select the Target property (text).
Specify a Property name (text, but could be any name).

The resulting code looks like this (comments omitted):

Again getter and setter methods are public, independently of the export settings, again the property is a bound property.

Using R-Beans     Top of page

You select R-Beans from a popup menu, similar to the one provided for selecting JavaBeans.


Double-clicking an R-Bean instance will display the R-Bean layout. There appears a button at the top-right corner of the editor area, clicking it will return you to the referencing layout.


To edit an R-Bean's public interface, select 'Edit R-Bean' either from the 'Layout' menu or from the context menu of the R-Bean layout.


Though R-Beans are in project scope, you can copy an R-Bean layout to a different project, but you must immediately export and compile a new R-Bean class (else the R-Bean attribute will be removed from the layout).

If you remove an R-Bean layout from a project, all R-Bean instances will automatically be removed from their respective layouts.

Event handling: R-Bean instances can be event sources or targets as well as property sources or targets. Event and property handlers defined in the R-Bean layout allow for event and property propagation between nested components.
Note: Event and property propagation between nested components of an R-Bean instance is performed by handlers of the runtime library and will therefore not show up in the RADi event monitor.


R-Beans and Internationalization     Top of page

If you are new to RADi, you may want to read the section about Internationalization first.

Changing the current locale of a localized project (using the 'I18n' menu) will affect the R-Bean layout, but not R-Bean instances. These are processed by the RADi runtime, which always loads properties files for the default locale (the one you did specify before saving properties files the first time).

R-Bean FAQs     Top of page

When should I use R-Beans?
If some visual entity is supposed to appear in several layouts.

What is the super type of an exported R-Bean?
If the R-Bean's top container has more than one child, the exported class extends RadiPanel (the top container).
If the R-Bean's top container has one single child (which might be a container containing other components), the exported class extends the child component's type.
Note: Non-component Beans are not children of the top container.

When is the R-Bean class reloaded?
Each time you switch from an R-Bean layout to another layout, the R-Bean's class file will be checked and will be reloaded if it has changed. (This means that, after editing and recompiling the code of an R-Bean class, you must select the R-Bean layout and then some other layout, else the class will not be reloaded).
Note: Because R-Bean instances process the layout definition file, you must save a changed R-Bean layout in order to update R-Bean instances. You must do this before you select another layout.

When should I re-compile an R-Bean?
After adding or removing components.
After changing component names or changing the "Inner class" attribute of containers.
After adding listeners or actions.
After changing the public interface.
If it is absolutely necessary to re-compile an R-Bean, RADi will show an appropriate prompt.

What is the difference between JavaBeans and R-Beans?
R-Beans depend on the RADi runtime library.
R-Beans are always derived from JComponent.
R-Beans are restricted in use without additional programming.
(On the other hand you can program an R-Bean, in the end it's just a piece of code.)
R-Beans are in project scope. One can not use the same R-Bean in different projects.
R-Bean information is stored together with the project, not as part of the layout definition file (this makes sense because the only thing the RADi runtime needs to know about an R-Bean is its class name).
One consequence is, that an R-Bean layout which you load into a different project will loose its R-Bean attribute. Even if you load a layout which references an R-Bean into a different project, the R-Bean class can not be loaded, because the ClassLoader is part of the R-Bean layout.

What about R-Bean performance?
Inside RADi, R-Beans do cause a performance fault, because classes of the runtime library must be loaded (this happens at startup while loading layouts. After this, reloading classes and instantiating R-Beans is a matter of a few milliseconds).
In a running application there is no performance fault, because classes of the runtime library already are loaded.