Tuesday, December 15, 2009

Custom JSF Components with Facelets

The Overview
Creating custom components can really clean up your faces pages and keep you from repeating yourself over and over. And its fun to do! There are a number of posts out there and tutorials about creating custom components, and often times they leave out the most important pieces of configuration. In this post I will specify how to create composite components with Facelets. This is different from the jsf style custom components in that these are much easier to create, require much less configuration, and often times solve the problem at hand very quickly.

The Affected files
  1. the Web Descriptor
  2. The component definition
  3. The tag library descriptor
  4. The pages that you insert the component into


The Web descriptor, (web.xml) tells your container about your tag lib descriptor file.

The component definition fie specifies how the component is laid out. It may have logic in it and you may pass parameters to it. It produces the markup that appears in your faces page.

The Tag Library descriptor is an xml file that describes to the container what to do when it encounters your custom component tag.

Finally, your pages need to include the tag for it to be seen.

Getting Started
The first thing to do when creating a component is to generate the markup, styling and any scripts that accompany it in a sandbox. Try inserting it in your pages and seeing what it looks like and get it to work correctly. Once this is done, you are ready to generate the reusable tag that will display your component each time you need it. In this case I made a progress bar for my application.

Directory Layout
Under WEB-INF, create a directory called facelets, with a sub directory called tags.
In the tags directory we are going to place our tag library decriptor and our component.

myProject.taglib.xml
The Tag Lib Descriptor file: (myProject.taglib.xml)

<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"facelet-taglib_1_0.dtd">
<facelet-taglib>
<namespace>http://www.yourId/jsf</namespace>
<tag>
<tag-name>progress</tag-name>
<source>progress.xhtml</source>
</tag>
</facelet-taglib>



The file specifies the following items:

namespace - Your unique id that wont conflict with other known urls. It does not need to exist on a server, it just needs to be unique. In this example I called it http://yourId/jsf. Any components that you place in this tag lib descriptor will be accessed in you pages using this as the uri to find this definition file. So in your pages that contain the component, the following tag will be added in your opening definitions:
xmlns:xx="http://www.yourId/jsf"
where xx will be the tag handle in the page.

tag-name is the name of this particular component. In this case it is a progress bar. In your page you will access it via xx:progress

source is the name of the file that we will create to define our tag - the markup.


web.xml
Now we need to tell the application about our library. In web.xml, create the following entry:

<context-param>
<param-name>facelets.LIBRARIES</param-name>
<param-value>/WEB-INF/facelets/tags/myProject.taglib.xml</param-value>
</context-param>

If you already have an entry like this, the param values can be a semi-colon delimited list.


progress.xhtml
So now we have our tag lib descriptor, and the container knows about it. Lets generate the component file. The name of the file must match the name in the taglib descriptor for the component. It is the source tag. So when the application encounters the tag name in the page, it looks up in the taglib descriptor (which it gets from the namespace definition) and finds the source file associated with the tag name.

This file also resides in WEB-IN/facelets/tags.

The file:



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions">

<ui:composition>

<span class="progressContainer" >
<div class="progressBar" >

<c:if>
...more markup
</c:if>

</div>
</span>

</ui:composition>
</html>




I've left out my markup, but you can put yours in. We will look at parameter passing a bit later. For now, lets just get you using a tag in your pages. At this point everything is set to go. You just need to include the definition for your library in your page, and then specify the tag in the page.

So in your page:

In the opening tag, include the definition:

xmlns:xx="http://www.yourId/jsf"

Note that this must match the namespace specified in your tag lib descriptor. Remember that this is an arbitrary name for id purposes only. The xx is an arbitrary handle for accesing the library in your page.

Then, in your page to use the tag you would call:


<xx:progress/>



OK So at this point the tag should appear in your pages where you specify it. In the next edition, we will discuss parameter passing and using jstl in the tags. I also like to include certain tags in my templates that pages use. This requires a different approach for parameter passing, as the template defines where the tag will be, but the pages may want to use the tag differently.

Hope that helps.

Tuesday, October 13, 2009

Refreshing Data in the UI

Once your application is up and running smoothly, all the data appears as it should, it may seem that all there is left to do is style it up and move on. But in high volume sites, or low volume sites with areas of high transaction, you need to ensure the user is seeing the latest information available. This needs to be done via XMLHttpRequests so that the page that the user is working on remains intact.

Lets first discuss the data is stored and retrieved.

In any web application, the user will request data and you present it. Often the state of the page is determined by the data that is present. So you want to limit the number of calls to the database for this information by caching it in your backing bean. This requires that you reset this data when appropriate. Once the page is loaded, the data remains flat on the page until the user interacts, or you cause an update. Thus we load the data on demand, or lazily, and then cache it until it needs refreshing.

Refresh from the UI is made by AJAX calls. The calls invoke backing bean actions based on the framework you are using. Apache Trinidad has a nice built in mechanism for making AJAX calls to the JSF.

In my backing beans, I add a PollListener method that resets the data I want to refresh in the UI. The method looks like this:

public void tableDataPoll(PollEvent ev) {
resetData();
}


When the bean gets the call from the AJAX event, it resets the underlying data so that when the page requests the data, it is pulled afresh. In the UI the call is made by adding a trinidad poll ( An AJAX call that runs at a certain interval) to the page:

tr:poll interval="30000" pollListener="{bean.tableDataPoll}" id="ajax1"

This causes an AJAX call to invoke my poll listener in the backing bean every thirty seconds. In order for the table of data to update, you need to add a partial trigger to the component that displays the data. This is done as follows:

tr:table value="{bean.backingData}" partialTriggers="::ajax1"

So the poll initiates an ajax call to the bean, resets the backingData in the bean, and the table refreshes by updating itself with the new value for the backing data.

It is incredibly easy to do.

On another project where I did not use Trinidad, we achieved the same by writing out the ajax calls. Basically, the pages would call your ajax javascript library with the ids of the objects to update, and your backing bean would change these values. I found that an extremely useful tool was a window within the page that showed the ajax calls. In the page, I added a div element such as:

div id = "div_ajax_log"
textarea id = "log_ajax" name = "status" rows = "25" cols = "55"
/div

I would have a javascript library for ajax, and in this library I would have a toggle to turn ajax logging on and off. I would also set the style for the div as none or block based on wheterh I was in debug /dev mode or not. That way if there was an issue in production, I could inspect the messages coming to and from the server to the page.

In my js file for ajax, I would specify whether we are logging, and the element to log to :
// Whether to log
var _logging = false;
// Where to log
var _log_elem;

I would then specify a logging function:

function logger(text, clear) {
if(!_log_elem) {
_log_elem=document.getEleemntById("log_ajax");
if(clear)
_log_elem.value="";
var old = _log_elem.value;
_log_elem.value = text + ((old) ? "\r\n" : "") + old;
}

You will need to add in some null checks and/or try blocks in the above basic version.

Then, in my ajax methods I would check to see if the logger was running and if so spit out information to the text area. For outgoing calls:

logger("AJAX Request: " + ((async) ? "Async" : "Sync") + " " + method + ": URL: " + url + ", Data: " + data);

Where the variables were passed in by the calling page. For outgoing responses, I would do the same - here the variable AJAX is the XMLHttpRequest generated in the original call.

logger(AJAX.status);

logger(AJAX.responseText);

The result is a conditional logger to the page with the information carried to and from the page in AJAX calls.

Hope that helps.

Tuesday, July 14, 2009

Testing Web Applications

How many times have you been on a project and seen changes to code cause the application to blow up, and yet the Unit Tests all succeeded? To avoid this situation I use HtmlUnit, an open source project distributed under the Apache License.

HtmlUnit emulates a browser that is visiting your web application. Coupled with JUnit, it allows you to write tests that click through the application just as QA does. It ensures that the functionality you put into your pages exists and works properly.

With HtmlUnit and Junit I am able to test most functionality in the web tier : page flow, form population and submission, javascript, popups, dialogs, and AJAX calls. I even created a suite of convenience methods to work with my Trinidad components.

The one shortcoming has been the ability to test Flex animations. These were always a black box to my test suites. However, Gorilla Logic has now released FlexMonkey, which is also based on HtmlUnit, and allows you to test the flex animations from an easy to use test suite.

I use these tests as both integration and unit tests. I ensure the application can be "clicked through"; that all pages appear at the correct time, and that interactions in the page all function correctly. I also test various scenarios that will occur in the application, and ensure that the application responds correctly based on the processing of the data passed in.

I no longer worry about the application blowing up in meetings or demos:

IT'S BEEN TESTED!!

Hibernate Search by Date

On the project I am on now, we use Dates as a basis for monetary calculations. The Dates are simply based on the day, month and year, disregarding hours, minutes and seconds. We store our dates after base-lining them - stripping out the H:M:S. This is achieved with Calendar utilities:

static Date baseLineDate(Date myDate) {
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(myDate);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}

Determining if a Date is before, after, or equal to another is straightforward thereafter- just use the Calendar before() and after() methods.

If you look in the database, the dates are stored as 01-Jan-2009. It would be tempting to simply run a Hibernate query that tests equality. You could simply generate a base-lined date and ask Hibernate to return the objects that have this Date. And it works.

However... Databases are part of the seedier side of the software town. Lurking there is data imported from other systems and/or updated by rogue administrators. The best way to handle all possible situations correctly is to use the Hibernate Criteria's between() method:


getCurrentSession().createCriteria( MyItem.class )
.add(Expression.between("myDateField", base-lined-Date, end-lined-Date))
.list();

Where the base-lined-Date has been base-lined as above, and the end-lined-Date corresponds to a Date that is the last millisecond of the day:

static Date EndLineDate(Date d){
if(d==null)return null;
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(d);
cal.set(Calendar.HOUR, 11);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.HOUR_OF_DAY,23);
cal.set(Calendar.MILLISECOND, 999);
return cal.getTime();
}

This solution pulls in all objects that have a certain Date defined by Day, Month and Year only.

Tuesday, March 24, 2009

Trinidad Draggable Dialogs

Users of Apache Trinidad may have run across the issue of not being able to move the Trinidad dialogs around the page. They always sit right in the center of your screen and of course block you from seeing the information behind. In release 1.02 the authors proposed that the dialogs should be made drag-able, however nothing has been done. The following is a simple solution I used to make the dialogs drag-able. If I had time, I would commit something to the project to handle this - although I believe the reason it has not yet been implemented is because of the amount of cross browser code needed to affect this. The following solution took about 5 hours to come up with and refine.

The trick with making the dialogs drag-able is that that the dialogs are generated after the page loads, use different markup depending on browser type and version, and the markup contains no ids on the DOM elements of interest. I implemented this for Firefox2, 3 and ie7. For other browsers, the dialog is rendered with standard behavior.


So lets get started:

Step 1: Add the mouse drag event script to the Trinidad dialog:

In your xhtml/jsp file that will display behind the dialog , add a trh:script call that is rendered conditionally based on browser. The call will need to wait until the page loads to execute, so I add a timer to delay invokation:

trh:script text="window.setTimeout('attachDraggabilityToDialog()', 500);"
rendered="#{UiUtils.supportsDialogDrag}"

partialTriggers="::pprDialogCallButton "


The text attribute calls the attachDraggabilityToDialog script 500 ms after the page loads ( I place the script at the bottom of the page. )

The rendered attribute calls a backing bean function that specifies whether the browser version is supported for dragging.

The Partial Triggers attribute references Trinidad element id that pops up the dialog - in this case the button.

Step 2. Create the script:

// the frame
var dialog_frameDiv= null;
// the title bar on the frame
var dialog_titleBar=null;
// the object to drag around
var dialog_dragObj = new Object();
var GECKO=0;
var IE=1;
var BR_VER=GECKO;
new Browser();




/**
* After the page has loaded, and the popup has been displayed,
* Call this function:
* e.g: window.setTimeout(attachDraggabilityToDialog, 500);
* NOTE _ WORKS IN FF2, 3 AND IE 7
*
*/
function attachDraggabilityToDialog() {
dialog_dragObj = new Object();
dialog_frameDiv= null;
dialog_titleBar=null;

if (BR_VER==GECKO) {
for(var i =0; i <
window.document.body.childNodes.length;i++) {
dialog_frameDiv= window.document.body.childNodes[i];
if(dialog_frameDiv!=null && dialog_frameDiv.nodeName=="DIV" && dialog_frameDiv.style.zIndex==5001) {
dialog_titleBar=dialog_frameDiv.childNodes[0];
break;
}
}
}
else if (BR_VER==IE) {
var _node = document.getElementsByTagName("iframe")[0].parentNode;
if(_node !=null && _node.tagName=="DIV"){
dialog_titleBar= dialog_frameDiv=_node;
}
}

if(dialog_titleBar !=null) {
if (BR_VER==IE) {
dialog_titleBar.attachEvent("onmousedown", callDrag);
dialog_titleBar.attachEvent("onmouseup", endDrag);
}
if (BR_VER==GECKO) {
dialog_titleBar.addEventListener("mousedown", callDrag, true);
dialog_titleBar.addEventListener("mouseup", endDrag, true);
}
}

}



Discussion: Based on browser version, we look through the generated markup in the page once the dialog has appeared and find the element based on attributes or expected location of the node in the tree. While not foolproof, this technique works in the many scenarios in our present application, as Trinidad generates the dialogs in a standard manner per browser and version.

The attachDraggabilityToScript injects event handlers onto the elements to be dragged. The event handlers are below:


function callDrag(event) {

var el;
var x, y;
dialog_dragObj.elNode = dialog_frameDiv;

if (BR_VER==IE) {
x = window.event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
y = window.event.clientY + document.documentElement.scrollTop+ document.body.scrollTop;
}
if (BR_VER==GECKO) {
x = event.clientX + window.scrollX;
y = event.clientY + window.scrollY;
}


dialog_dragObj.cursorStartX = x;
dialog_dragObj.cursorStartY = y;
dialog_dragObj.elStartLeft = parseInt(dialog_dragObj.elNode.style.left, 10);
dialog_dragObj.elStartTop = parseInt(dialog_dragObj.elNode.style.top, 10);

if (isNaN(dialog_dragObj.elStartLeft)) dialog_dragObj.elStartLeft = 0;
if (isNaN(dialog_dragObj.elStartTop)) dialog_dragObj.elStartTop = 0;

if (BR_VER==IE) {
document.attachEvent("onmousemove", startDrag);
document.attachEvent("onmouseup", endDrag);
window.event.cancelBubble = true;
window.event.returnValue = false;
}
if (BR_VER==GECKO) {
document.addEventListener("mousemove", startDrag, true);
document.addEventListener("mouseup", endDrag, true);
event.preventDefault();
}

}


function startDrag(event) {

var x, y;


if (BR_VER==IE) {
x = window.event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
y = window.event.clientY + document.documentElement.scrollTop+ document.body.scrollTop;
}
if (BR_VER==GECKO) {
x = event.clientX + window.scrollX;
y = event.clientY + window.scrollY;
}


// Move drag element by the same amount the cursor has moved.

dialog_dragObj.elNode.style.left =(dialog_dragObj.elStartLeft + x - dialog_dragObj.cursorStartX) + "px";
dialog_dragObj.elNode.style.top =(dialog_dragObj.elStartTop + y - dialog_dragObj.cursorStartY) + "px";

if (BR_VER==IE) {
window.event.cancelBubble = true;
window.event.returnValue = false;
}
if (BR_VER==GECKO) ;
event.preventDefault();
}


function endDrag(event) {
if (BR_VER==IE) {
document.detachEvent("onmousemove", startDrag);
document.detachEvent("onmouseup", stopDrag);
}
if (BR_VER==GECKO) {
document.removeEventListener("mousemove", startDrag, true);
document.removeEventListener("mouseup", stopDrag, true);
}
}



Discussion : The above event handlers move the DOM element based on mouse movements after the user mousesdown on the element, and releases once the user mouses up based on browser version.


Finally, I have a simple browser detect , knowing that my script will not be called unless the browser is Firefox2, 3 or IE 7.


function Browser() {
var ua, i;
ua = navigator.userAgent;
if ((i=ua.indexOf("MSIE")) >= 0) {
BR_VER=IE;
}
}


In my backing bean, I have the following browser detection code that conditionally renders the call to the script based on its findings:



/**
* Currently only ff2,3 ie 7
* @return tru if the browser is one of the above.
*/
public boolean getSupportsDialogDrag() {
String ua = UiBaseUtils.getRequest().getHeader("User-Agent");

if(ua ==null)
return false;

if(ua.contains("MSIE 7"))
return true;
if(ua.toUpperCase().contains("GECKO")){
if(ua.contains("Firefox/3."))
return true;
if(ua.contains("Firefox/2."))
return true;
}
return false;

}



That's it.

I believe the correct way to do this would be to donate time and code to the Trinidad Project. I hope to do this , but I needed to come up with a quick solution that worked. I was able to commit this in less than 24 hours after getting the requirement, so please take this solution with this caveat in mind. QA has found no issues, and user feedback has been positive.

Hibernate AliasToBean Transformer

Problem: You need to access values from tables that are not hibernate entities, in an aplication that uses hibernate to access the database.

Problem: You want to access a couple columns from any number of tables in your database without bringing back all the associated objects.

Solution: AliasToBean Transformer allows you to retrieve specific information in non entity beans.

This hibernate API call will allow you to run sql against your database and populate a list of pojos that are not a hibernate entity. This technique is great when you need specific information or perhaps you want information fom multiple tables.


Your pojo:

Class PlainOldObject {
String s1;
String s2;

public String getS1() {return s1;}
public String getS2() {return s2;}

public void setS1(String s1) {this.s1=s1;}
public void setS2(String s2) {this.s2=s2;}

}

Then in a hibernate dao :

publc List lookupPlainOldObects() {

// the sql with a reference to the s1 and s2 fields in our object
String sql="select tableX.col1 as s1, tableY.colx as s2 where blah blah blah";

List list = getCurrentSession().createSQLQuery(sql)
.addScalar("s1")
.addScalar("s2")
.setResultTransformer(Transformers.aliasToBean(PlainOldObject.class ) )
.setCachMode(CacheMode.GET)
.list();

return list;

}

This avoids your needing to cycle over multiple objects to pull in the information you need. It also alleviates the need to cycle over Object[] s to sort through your results.

A couple notes:

1. Use the set scalar method to convert the variables in your sql to the fields in your pojo.
2. Use CacheMode.GET to keep these ojects out of the hibernate session cache.




Monday, March 2, 2009

Passing Parameters via JSF

JSF allows us to cause updates to via various listeners: actionListseners, disclosureListeners, valueChangeListeners, and phaseListeners to name a few. Sometimes however, you may want to pass a parameter in to a generic method - perhaps to grab the value of an enumeration or access a users ability to view components based on Role.

One little known feature of JSF is that you may access elements of a java.util.Map. This allows us to pass in a key to a map object in one of our contexts, and the map passes back the value pair via the get(Object) method.

The notation in your jsf page would be:

value="${yourContextHandle.mapObject['mapKey']}"

where

yourContextHandle is an object in one of the contexts you use to access backing code
mapObject is a java.util.map that is available on the above object via getMapObject()
mapKey is the parameter passed in to find the object from the map.



In you backing code, generate an object that extends java.util.Map. You will need to implement quite a few methods, so I typically create a base object stub that handles the overriding of the methods beyond get(Object). In the below example, I call this MyBaseJSFMap. Then I extend this object and simply override get(Object);

But how do you get the answer you need?

Consider the following Map :


public Class MyJSFMap extends MyBaseJSFMap{

public Object get(Object o) {
return doSomething((String)o);
}

public String doSomething(String str) {
// your businessLogic here - perhaps a lookup to a database or a pull from a map.
}
}




Thursday, February 5, 2009

Understanding Hibernate Delete Orphan issues

Ever wonder how Hibernate knows to follow the annotation "CascadeType.DELETE_ORPHAN"?

The short answer is that Hibernate keeps track of removals from these collections. When you remove an object from the collection, the status of that object is set to Status.DELETED or Status.GONE if the object is still in the persistence context. When hibernate saves the object tree that contained these ex-collection objects, it sees that the object has been dereferenced, marked for deletion, and is then removed from persistent storage and the persistence context.

Thats how it is supposed to happen.

Ever wonder why you are getting the error :
org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity ?

Lets say that you have an object with a collection that is cascade type delete orphan, and it has some child entities in it. And lets say that you change this collection simply by calling the setter on the parent object:

parent.setChildren(someDifferentSet);

or

parent.setChildren(null);

The children that were in the collection are still in the persistent context. However, they are no longer referenced by the parent object, and Hibernate never said goodbye to them. In the Collections class (org.hibernate.engine.Collections) , the method processDereferencedCollection(Collection, Session) throws a hibernate exception when it finds these items in the persistence context, and their Status is not set to GONE or DELETED. The ensuing error message: 'A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity: ' followed by the parent entity name is shown.

The proper way to handle this situation where you want to replace an existing collection would be:

parent.getChildren().clear();
parent.getChildren().addAll(someDifferentSet);

Similiarly, if you just wanted to remove a child from the collection:

parent.getChildren().remove(child);

By calling the collections manipulations, hibernate is kept up to date with the status of the objects within and without the collection. It then manages the objects in the persistence session properly.



Sunday, January 11, 2009

Dynamically generated Trinidad Component Trees and Input Values

I recently generated JSF pages dynamically with components from Apache Trinidad. The results are wonderful - and saved a great deal of iterative development time by allowing business analysts to specify the UI for various business scenarios. (For those interested I explain the basics of doing this later in this blog.)

We of course find a few issues:

1. When Using PPR, values do not always match bindings.
2. Components sometimes disappear!

Some of the components used PPR on the front side to update other components. I ran into a few issues while validating these fields - the values did not match the values shown in the UI. I scratched my head and rolled up the sleeves.

The issue is that JSF has 2 notions of values for an input component:

1. The component binding.
2. The component value.

The component value is typically the value of the binding. However, if you perform an XmlHttpRequest (PPR), these values may be out of sync. The scenario I used was that I generate the components and specify bindings to backing beans. This works fine until a PPR request is made and you update the model. The UI value becomes out of sync with the backing model. There are a few solutions to this issue:

1. Call comp.setValue(the value) on the actual component. This will require accessing the component directly.
2. Call comp.resetValue() - this syncs the value to the binding but also requires that you access the component on the server.
3. Use PartialTriggers when generating the component. This requires that you specify the id of the components that will cause a refresh of the value, and that you keep track of these ids. Then you specify the partial triggers on the component at the time of component generation.

I found that solution 3 works best for me, as I found another issue with generating components server side and using AJAX on the front. Sometimes, inexplicably, components would disappear. The reason for this is that Trinidad generates ids for components, and when you have components generated on the fly, there seems to be competition among the components for the ids. This seems to be a result of mixing generated and dynamically generated ids. The solution for this is to specify all ids for your generated components. Coupled with the task of specifying partialTriggers and using ids for javascript calls, this is the best comprehensive and cohesive approach.

A little example of a dynamically generated UI :


In your UI page you simply add a container with a binding to a managed bean. In the following line, I specify a panelAccordion (without opening and closing brackets) :
tr:panelAccordion binding="#{myManagedBean.accordionX}"

then in your backing bean you generate the PanelAccordion:

CorePanelAccordion accordionX = new PanelAccordion();

Make sure that you provide public access to this component. You then build the component by adding boxes, tables, and inputs as you need. You also set the various attributes on all the components.

For instance, lets add a Detail Item with a box and an input with a button:

FacesContext fc = FacesContext.currentInstance();
CoreShowDetailItem tab1 = new CoreShowDetailItem();
// the following names are the handles you would call in the ui.
String tab1Binding = "myManagerKeyString.tab1Name";
tab1.setValueBinding("binding" , fc.getApplication().createValueBinding("#{" + tab1Binding + "}"));

tab1.setDisclosed(true);



CorePanelBox pb1 = new CorePanelBox();
pb1.setStyleClass("yourStyleClass");



CoreInputText comp = new CoreInputText();
comp.setId(genYourId());
comp.setLabel("Label for Component");
comp.setConverter(new YourCompConverter());

// This is the value binding to the backing pojo
String compBindString = "myManagerKeyString.pojo.compAttributeRelationName";
comp.setValueBinding("value", fc.getApplication().createValueBinding(#{"+ compBindString + "}"));


CoreCommandButton button = new CoreCommandButton();
button.setText("GO");
addButton.setId(genYourId());

// create a methodBinding
String actionBindingString = "myMangerKeyString.go";
MethodBinding mb = fc.getApplication().createMethodBinding("#{" + actionBindingString + "}"));
button.setAction(mb);


Now lets add the components:


pb1.getChildren().add(comp);
pb1.getChildren().add(button);
tab1.getChildren().add(pb1);
accordionX.getChildren().add(tab1);

Then when the UI is displayed, it references accordionX, and in the backing bean you generate this UI. Your managed bean needs to provide access to the actions and the pojo. This was a simple case and you can of course enhance you components by specifying any more attributes.

A couple pieces of advice:

1. Specify styleClasses and use css to control layout.
2. ValueBindings can be used to specify all the attributes that you normally specify client side. For instance, if the style of a component is bound to a server side call:

String styleBinding= "myMangerKeyString.someStyleBindingCallName";
comp.setValueBinding("styleClass", fc.getApplication().createValueBinding("#" + styleBinding + "}" ));

You can use this to bind any attribute to a server call.


In a recent application, I used xml to specify the fields and their attributes possible in a UI. I then allowed business analysts to choose which components displayed when, and even some of the attributes such as label and order. Then, when the call is made to display a container, I generate the UI based on their selections. It worked quite well.