Custom (user-defined) GUI components in ADF

JDev: 12.2.1.3.0
Source: 1) CustomComponent , 2) CustomComponentApp

A very less-used, yet powerful, feature of Oracle ADF is its ability to allow users to create custom (declarative) UI components. The steps to create such a re-usable component is a bit elaborate and clumsy, but the fruit of the hard-work is quite sweet!

This is going to be quite a large blog. So I will break this into 2 sections. However, just to get your attention, this is what we intend to achieve in the end:

This is what our jspx code will be


Section 1 - Define the component

Create an ADF application, with the default ViewController and Model projects. I have renamed ViewController to DeclarativeComponent in my case, and have removed the Model project. An alternate starting point would be to create an empty Java application and add a project, but I chose this path so as to ensure that all the required libraries get included automatically and save me the hard work!

Once the application structure is created, right click on the project and create a new “ADF Declarative Component (JSF/Facelets)”. I will call it “tablesearch”.

The declarative component wizard

Click on the “Add Tag Library” button. This is where you enter the details for the tag library which will be supporting this declarative component. Once this step is completed, the JDeveloper will create a file called “declarativecomp-metadata.xml”, with this information.


Next it is time to add the properties which will define this component. These properties are the ones which will be displayed on the Property Palette, and can be configured for this component at design time.

Here’s a list of properties (or attributes) that I will be creating. You may create additional attributes, depending on how much you want the user to customize a component at design time.


Attribute name
Attribute type
Default value
Required
searchHeaderLabel
java.lang.String

No
displaySearchPanel
java.lang.Boolean
true
No
discloseSearchPanel
java.lang.Boolean
true
No
criteriaName
java.lang.String

Yes
tableBinding
java.lang.String

Yes
resultsTableRowHeight
java.lang.Integer
10
No
resultsTableEmptyText
java.lang.String
No data found.
No


Before we proceed further, we will create a new deployment profile for this project, which will deploy this application as an ADF Library Jar File.


Let us now use this profile to build the application. Once the jar is built, we find something interesting! JDeveloper automatically creates a few extra classes for the declarative component. These classes are not available at design time, but only after compilation.

1) TablesearchComponent.class, 2) TablesearchHandler.class and 3) TablesearchTag.class
If we open up the TablesearchComponent.class, we see that it contains getter methods for all the attributes we have defined on our component. This is something we will need, and will leverage.


TablesearchComponent.java - Getter methods for component attributes

We will now need a backing bean, to provide EL support to the component’s properties. I have created a TablesearchDefinition class. From this bean, we will access the TablesearchComponent class, through the comp attribute.


The comp attribute is available from the actual declarative component XML (jspx) file.

tablesearch.jspx - componentVar = "comp"

Note: You might see an error when you reference the TablesearchComponent class during development. This is expected, as the TablesearchComponent class is still not compiled and created. However, that will not stop you from compiling your project. Once the project is built, this class is created, and your backing bean will have access to it.

tablesearch.jspx

We will need the two attributes which are marked as required – criteriaName and tableBinding. We will build the remaining properties from these two, as shown below:

TablesearchDefinition.java - this is your backing bean

Quick note - an interesting trick would be the way we access the headerText of the table columns. In order to allow us the flexibility of accessing the label hints from the bundle file, we access the label from the bindings.VO-INSTANCE.hints.ATTRIBUTE-NAME.label map.



Before we build the jar, let's have a look at the final application structure.



We now re-build the jar file and we have the re-usable custom component ready.

Section 2 - Use the component

We build another ADF application, with the usual Model and ViewController projects. This application will be based on the default HR schema.

I have 2 view objects - on Departments and Employees tables. Each view object has a view criteria defined on it - DepartmentsSearchCriteria and EmployeesSearchCriteria - respectively.

I wouldn't go into the details of this. The setup of the application would be pretty straight-forward. The only task which we need to do is to import the custom component jar into the view controller project.


Once we import this we get an interesting behaviour. We get to see our custom component in the property palette. We can actually drag and drop this component onto our page.




The tree and search region bindings have been created manually. The appropriate values have been populated into the tablesearch component's required attributes.

criteriaName="EmployeesSearchCriteriaQuery"
tableBinding="EmployeesVO1"


Well that is all. Going forward, you only need the binding definitions of the iterator and search region. The GUI code is reduced to a call to <cc:tablesearch/>!

Cheers!

Comments