|
|
Advanced Tutorial - Component Registration - Create a custom component
SUMMARY
Component registration is a very important aspect of XUI as it allows you to use components which are not included in the standard XUI libraries. As you develop more applications with XUI you will build up a library of reusable components for your application development.
FURTHER READING There is an article on this subject published on XUI Zone. Up to now we have been using the components which come as part of the Xui Core libraries, whether they are Swing or AWT. Now we will introduce the idea of component registration in order to use non-core components. In this step we will show a navigation status component in the appstatus frame created in the previous step which will give feedback about where the user is in the data entry process.Text written in red shows where the user is currently in the application process. Grey text indicates stages already completed and black text shows stages which have yet to be done. The new component will use the navigation model which was introduced in the Library Functions step. Begin by creating the outline of the new NavViewer component class. Listing 1 - NavViewer.java
public class NavViewer extends JPanel {
private XStyle style, defaultStyle, currentStyle, doneStyle;
private String styleStr, defaultStyleStr, currentStyleStr, doneStyleStr;
XStyleManager styleMgr;
private XBaseModel navModel;
private String navModelPath;
ResourceBundle rb;
private int pageNum;
private int startRepeat, endRepeat, currentCust;
private XProject project;
public NavViewer()
{
project = XProjectManager.getCurrentProject();
styleMgr = project.getStyleManager();
rb = project.getResourceBundle( project.getStartupParam( "Language" ) );
}
public void paint (Graphics g )
{
super.paint( g );
}
private void setStyle( Graphics g, XStyle style )
{
g.setColor( style.getStyleAsColor( XStyle.COLOR_FORE ) );
g.setFont( styleMgr.getFont( style ) );
}
public void setStyle( String stylename )
{
styleStr = stylename;
style = styleMgr.getStyle( stylename );
}
public String getStyle()
{
return styleStr;
}
public void setDefaultStyle( String stylename )
{
defaultStyleStr = stylename;
defaultStyle = styleMgr.getStyle( stylename );
}
public String getDefaultStyle()
{
return defaultStyleStr;
}
public void setCurrentStyle( String stylename )
{
currentStyleStr = stylename;
currentStyle = styleMgr.getStyle( stylename );
}
public String getCurrentStyle()
{
return currentStyleStr;
}
public void setDoneStyle( String stylename )
{
doneStyleStr = stylename;
doneStyle = styleMgr.getStyle( stylename );
}
public String getDoneStyle()
{
return currentStyleStr;
}
public void setNavModelPath( String path )
{
navModelPath = path;
navModel = ( XBaseModel )project.getModel().get( navModelPath );
}
public String getNavModelPath()
{
return navModelPath;
}
public void setCurrentPage( int page )
{
pageNum = page;
}
public void setApplicant( int applicant )
{
currentCust = applicant;
}
}
This class contains several setter and getter methods which will be used to setup the component information. The setNavModelPath sets the path into the XModel which contains the page definitions. Four different styles are set which will be used to paint the page information which is carried out in the paint function. The component definition file components.xml now needs to be defined. Listing 2 - components.xml
<Components>
<Component name="NavViewer" class="net.xoetrope.mortgage.comp.NavViewer">
<Property name="Style" mode="Normal" type="both"/>
<Property name="DefaultStyle" mode="Normal" type="both"/>
<Property name="CurrentStyle" mode="Normal" type="both"/>
<Property name="DoneStyle" mode="Normal" type="both"/>
<Property name="NavModelPath" mode="Normal" type="both"/>
</Component>
</Components>
The component is given the name NavViewer. Each of the properties which will need to be set from the page declaration is defined using a Property node. Now we can set about defining a NavViewer in the appstatus.xml page. Listing 3 - AppStatus.xml
<XPage class="net.xoetrope.mortgage.AppStatus" style="Heading" resource="">
<Components>
<NavViewer name="navViewer" x="0" y="0" w="145" h="400" Style="status"
DefaultStyle="status/default" CurrentStyle="status/current"
DoneStyle="status/done" NavModelPath="navigation"/>
<Label x="149" y="0" w="1" h="500" style="banner" opaque="true"/>
</Components>
</XPage>
The component is defined using the node name NavViewer and the styles and model path are set as attributes. The modified AppStatus class follows... Listing 4 - AppStatus.java
public class AppStatus extends XPage implements NavigationListener {
NavViewer navViewer;
public void pageCreated()
{
navViewer = ( NavViewer ) findComponent( "navViewer" );
}
public void navigate( int page )
{
Container c = getParent();
c.setVisible( page == 0 ? false : true );
c.getParent().doLayout();
navViewer.setCurrentPage( page );
}
public void setApplicant( int applicant )
{
navViewer.setApplicant( applicant );
}
}
The pageCreated function creates a reference to the NavViewer object. In the navigate function the current page is passed to the navViewer object. The setApplicant function passes the current applicant to the navViewer object The NavViewer class can now be completed so as to output the application progress... Listing 5 - NavViewer.java
public void paint (Graphics g )
{
super.paint( g );
setRepeats( navModel );
g.setColor( style.getStyleAsColor( XStyle.COLOR_BACK ) );
g.fillRect( 0, 0, getWidth(), getHeight() );
int currentY = 20;
for ( int i = 1; i < navModel.getNumChildren(); i++ ) {
if ( i == startRepeat ) {
currentY = paintRepeats( g, currentY );
i = endRepeat;
} else {
XBaseModel mdl = ( XBaseModel ) navModel.get( i );
String summary = XModelHelper.getAttrib( mdl, "summary" );
if ( summary != null ) {
if ( i < pageNum )
setStyle( g, doneStyle );
else if ( i == pageNum )
setStyle( g, currentStyle );
else
setStyle( g, defaultStyle );
g.drawString( summary, 5, currentY );
currentY += 20;
}
}
}
}
private int paintRepeats( Graphics g, int currentY )
{
XBaseModel numAppsMdl = ( XBaseModel )project.getModel().get(
"mortapp/numApps" );
int numApps = XModelHelper.getIntValue( numAppsMdl );
for ( int cust = 1; cust <= numApps; cust ++ ) {
for ( int page = startRepeat; page <= endRepeat; page++ ) {
if ( ( page == pageNum ) && ( cust == currentCust ) )
setStyle( g, currentStyle );
else if ( ( page < pageNum ) && ( cust == currentCust ) )
setStyle( g, doneStyle );
else if ( cust < currentCust )
setStyle( g, doneStyle );
else
setStyle( g, defaultStyle );
XBaseModel pageMdl = ( XBaseModel ) navModel.get( page ) ;
String summary = XModelHelper.getAttrib( pageMdl, "summary" );
g.drawString( summary + " (" + cust + ")", 5, currentY );
currentY += 20;
}
}
return currentY;
}
private void setRepeats( XBaseModel navModel )
{
for ( int i = 1; i < navModel.getNumChildren(); i++ ) {
XBaseModel mdl = ( XBaseModel ) navModel.get( i );
if ( XModelHelper.getBooleanValue( mdl, "startrepeat" ) )
startRepeat = i;
if ( XModelHelper.getBooleanValue( mdl, "endrepeat" ) )
endRepeat = i;
}
}
private void setStyle( Graphics g, XStyle style )
{
g.setColor( style.getStyleAsColor( XStyle.COLOR_FORE ) );
g.setFont( styleMgr.getFont( style ) );
}
This code now has the effect of outputting the page summaries in various styles depending on where the user is in the application process. The text being output is being retrieved from the summary attribute of the navigation model so that needs to be modified as follows... Listing 6 - navigation.xml
<dataset id="navigation">
<page id="welcome" value="welcome" />
<page id="personal" value="personal" startrepeat="true" title="PER_HEADING"
summary="Personal Details"/>
<page id="bank" value="bank" endrepeat="true" title="BANK_HEADING"
summary="Bank Details"/>
<page id="finance" value="finance" title="FINANCE_TITLE"
summary="Financial details"/>
<page id="finish" value="finish" summary="Save Application"/>
</dataset>
Run the application and it will appear as in the screenshot. Log in or register to download the source code for this step. |