Category Archives: Web UI Components

Relatively Positioning Web UI Components

This tip is applicable to NetBeans IDE (versions 5.5.1 and 6) and the Sun Java Studio Creator IDE

If, when using the Visual Designer in a Visual Web application (grid layout), you want to position a component relative to the width of the browser so that when the user widens or shortens the browser, the component moves relatively, try the following steps:

  • Select the component.
  • In the Properties window, click the ellipsis (…) button
    for the Style property.

  • In the Style dialog box, select Position.
  • In the Position section, set the Mode to Relative.
  • Set either the Right or Left value to a number, such as 30. This value is the percent of the browser width to the right or left of the component, respectively. For example, a Left value of 30 will place the component’s left side 30% in from the left.
  • Select % from the drop-down list for the value that you just entered.
  • For the opposite side, select <Not Set> from the drop-down list. For example, if you set the Left to 30%, select <Not Set> from the drop-down list for Right
  • Click OK.

SqlException: At least one parameter to the current statement is uninitialized

When you do the Using Databound Components to Access a Database tutorial, you learn how to use the Query Editor on the rowset to build the SQL statement to retrieve the desired set of data. You also learn that for every ? (parameter) in your query, you need to call setObject() on the rowset before the query is executed. Take, for example, the following query.

SELECT ALL TRAVEL.TRIP.TRIPID,
TRAVEL.TRIP.PERSONID,
TRAVEL.TRIP.DEPDATE
FROM TRAVEL.TRIP
WHERE TRAVEL.TRIP.PERSONID = ?
AND TRAVEL.TRIP.TRIPTYPEID = ?

This query has two parameters, PERSONID and TRIPTYPEID. What this means is that you have to provide values for these two parameters before the rendering phase. You typically do this in the prerender() method, as shown in the following code example.

public void prerender() {
if ( personIdDD.getSelected() == null ) {
try {
personDataProvider.cursorFirst();
getSessionBean1().getTripRowSet().setObject(
1, personDataProvider.getValue("PERSON.PERSONID"));
getSessionBean1().getTripRowSet().setObject(
2, "4");
tripDataProvider.refresh();
} catch (Exception e) {
error("Cannot switch to person " +
personDataProvider.getValue("PERSON.PERSONID"));
log("Cannot switch to person " +
personDataProvider.getValue("PERSON.PERSONID"), e);
}
}
}

If you forget to set the parameters before the rendering phase, you usually get the following error.

SqlException: At least one parameter to the current statement is uninitialized.

You will also get an error like this if you do not set all the parameters. Such as only calling setObject(1, somevalue) when you have two parameters in the query.

Another common error is to forget to edit the query to add the parameters. If you call setObject(1, somevalue), but your query has no parameters (no ?), you might get an error like the following.

java.lang.NullPointerException
at org.apache.derby.client.am.PreparedStatement.checkForValidParameterIndex(Unknown Source)

Similarly, if you call setObject(2, somevalue) when your query has only one parameter, the server will emit something like the following message.

SqlException: The parameter position '2' is out of range.
The number of parameters for this prepared  statement is '1'

Laying Out Multiple Table Components

You can use the layout components, such as the Group Panel and the Grid Panel, to easily layout and size container components, such as the Table component. In the screen shot above, the two tables on the left are in a Group Panel, and the two on the right are in a Grid Panel. I can resize or move either panel in the Visual Designer, and the contents will resize and move in accordance (they won’t resize in the Visual Designer, but they will resize in the client). The trick is to set the width property of each tables to 100% so that they resize based on the size of their container.

Because the Visual Designer does not display the widths of the tables accurately, you have to right-click on the page and choose Preview in Browser to get a feel of how the tables will actually appear in the client.

Tips:

  • Set the Group Panel component’s block property to true. This encloses the panel in a <div> tag.

  • You can set the Group Panel component’s separator property to <br /><br /> to put spacing between the tables.
  • Set the Table component’s width property to 100%. If you make changes to the table, the IDE may reset this property so keep checking to make sure it is 100%.
  • I find it best to leave the Table Column width properties blank or set them at percentage amounts, such as 10%.

Page Fragment Tips

7/16/07 Update: Thanks to Antonio, this blog entry is now available in Spanish.

Page fragments enable you to add a particular set of components, action handlers,
and functions to a bunch of web pages. When you add a Page Fragment Box to a
page, you are first given the option of choosing an existing page fragment or
creating a new one, and then the IDE adds a <jsp:directive.include>
tag to the main page (the page that includes the fragment). When you create
a page fragment, the IDE adds both a .jspf file and a backing bean
to the project.

The <jsp:directive.include> directive is not the same as,
the <jsp:include> standard action. The directive causes the
contents of the page fragment to be placed into the main page’s .jsp
before the .jsp file is translated into a servlet.

The page fragment’s backing bean extends AbstractFragmentBean,
which, unfortunately, does not provide the preprocess or prerender
methods. It only provides the init and destroy methods.
When a person lands on the page from another destination, such as by typing
in the URL or clicking a link, the server instantiates the fragment’s backing
bean (and thus calls the init method) the first time that fragment
is referenced. In general, this is likely to happen during the render response
phase. On a postback (that is, when the page redisplays itself in response to
a page submission) , the fact that the saved component state includes component
bindings to properties in the fragment’s backing bean will cause the server
to instantiate the page fragment’s backing bean much earlier.

Because the page fragment’s init method can be called early in
the lifecycle,
you cannot reference or set component values in the init method.
Conversely, a page fragment’s init method might not be called until
during or after the main page’s prerender call. A workaround for
this is to put methods in your page fragements and call those methods from the
main page’s prerender. For example, you can add a prerenderFragment
method in each of your page fragments. Then for each fragment that you include
in the main page, add code like the following:

public void prerender() {
TopFragment topFragment = (TopFragment)getBean("TopFragment");
topFragment.fragmentPrerender();
...
}

Here are some code snippets to illustrate some common page fragment tasks:

Passing Data Between the Main Page and the Page Fragment

You can pass data to a page fragment through the a managed bean (request bean, session bean,
application bean), or through function arguments as shown below

In the following snippit, the main page passes information to the page fragment
by argument:

  public void prerender() {
Bike bike = getSessionBean1().getBike();
...
PriceTable priceTable = (PriceTable) getBean("PriceTableFragment");
totalsSubtotalPrice.setText(priceTable.subtotal(bike));
}

Here, the main page sets the values in the request bean, which the page fragment
then picks up and uses. This is from a web application where the user selects
an item from a drop-down list in the main page, which, in turn, refreshes the
trip data provider in the page fragment.

    // Page Fragment
public void fragmentPrerender() {
if (getRequestBean1().getPersonId() != null) {
try {
getSessionBean1().getTripRowSet().setObject(
1, getRequestBean1().getPersonId());
tripDataProvider.refresh();
} catch (Exception e) {
error("Cannot switch to person " +
getRequestBean1().getPersonId().toString());
log("Cannot switch to person " +
getRequestBean1().getPersonId().toString(), e);
}
}
}
    // Main Page
public void prerender() {
// If not a postback, set the default person
if (getRequestBean1().getPersonId() == null) {
try {
personDataProvider.cursorFirst();
getRequestBean1().setPersonId(
(Integer)personDataProvider.getValue("PERSON.PERSONID"));
} catch (Exception e) {
error("Cannot switch to person " +
personDataProvider.getValue("PERSON.PERSONID"));
log("Cannot switch to person " +
personDataProvider.getValue("PERSON.PERSONID"), e);
}
}
Fragment1 fragment1 = (Fragment1) getBean("Fragment1");
fragment1.fragmentPrerender();
}

Changing Component Properties in a Page Fragment

The main page can access and modify components in the page fragment through
the page fragment’s bean object, as shown below:

  public void prerender() {
Navigation navigationFragmentBean = (
Navigation)getBean("Navigation");
Hyperlink homeLink = navigationFragmentBean.getHomeLink();
homeLink.setDisabled(true);
}

Determining What Page the Page Fragment is Included In

In this code snippet, the page fragment changes its apperance based
on what page it is being displayed in.

    public void fragmentPrerender() {
// If they are done, show the checkout button
String page;
String viewId = getFacesContext().getViewRoot().getViewId();
if (viewId == null || viewId.length() == 0 || "/".equals(viewId)) {
page = "";
} else {
int pos = viewId.lastIndexOf('/');
if (pos == viewId.length() - 1) {
// last char in viewId is '/'
viewId = viewId.substring(0, pos);
pos = viewId.lastIndexOf('/');
}
//ok if pos is -1, then pos+1 will be 0
page = viewId.substring(pos+1);
}
checkoutButton.setRendered(FINAL_ORDER_PAGE.equals(page));
}

Using a Tab Set in a Page Fragment for Navigation

Yossarian, a Creator/NetBeans IDE user, submitted this tutorial to the Creator
Community Docs Site: Simple
Page Fragment Menu Example
.

Dynamically Rendering a Page Fragment Component From the Main Page

Here is a snippit where the main page dynamically renders a tree in a page fragment

    public void makeTree() {
Fragment2 pgfrag = (Fragment2)getBean("Fragment2");
List children = pgfrag.getDisplayTree().getChildren();
TreeNode personNode = new TreeNode();
personNode.setId("node1");
personNode.setText("Shari Oln");
children.add(personNode);
}

Other Examples

In Winston’s blog
he points to Josh’s web site, which uses VWP page fragments to do wonderous
things. How about you? Do you have some super page fragment tips to share? If
so, post them to the comments below to share with other VWP developers.

Coordinated Drop-Down Lists

I have seen a lot of inquiries in the users alias and the forum
about how to do coordinated drop-down lists. Coordinated drop-downs
are basically a set of nested master-detail records that follow
the same pattern that we show in Using Databound Components to Access a Database. With coordinated drop-downs,
whenever the user selects a new item from the master drop-down, you
need to refresh the list in the detail drop-down.

In the following example, I show how to coordinate drop-down
lists that contain data from the Travel database. The first drop-down
lists all the PERSON records. The second drop-down shows all the
TRIP records for the selected PERSON, and the third drop-down
shows all the FLIGHT records for the selected TRIP. Finally,
the detail data shows data from the selected FLIGHT.

The trick with coordinating multiple drop-downs, is that you
need to trickle down the refreshing of the lists. A change in the
first drop-down’s selection requires refreshing the second list, which
in turn, requires refreshing the third list, and so on.

In this example, I took the easy route. When the user makes
a new selection from the PERSON drop-down, I select the first
record by default and coordinate the TRIP drop-down by showing
all the trips for the first-person. Then, I show all the flights
for the first TRIP record, and the detail data for the first FLIGHT
record.

  1. Create your Sun Java Studio Creator (JSC) or NetBeans Visual Web Pack
    (VWP) project.

  2. Drop three Drop Down List components, a Property Sheet
    component, and a Message Group component onto the page
    in the Visual Designer. The Message Group component
    is to help diagnose problems if something goes wrong.

  3. Select each component and, in the Properties window,
    change the id property
    as follows, from top to bottom:

    1. personDD
    2. tripDD
    3. flightDD
  4. Drag the PERSON table from the Travel database (in the Servers
    window for JSC, and in the Runtime window for VWP), and drop it
    on the personDD Drop Down List component in the Visual Designer.

  5. Drop the TRIP table on the tripDD component, and drop the
    FLIGHT table on the flightDD component.

  6. Right-click each Drop Down List component and choose Bind
    to Data. Make the following selections:

    1. personDD. Value Field: PERSON.PERSONID, Display Field:
      PERSON.NAME
    2. tripDD. Value Field: TRIP.TRIPID,
      Display Field: TRIP.DESTCITY
    3. flightDD. Value Field: FLIGHT.FLIGHTID, Display Field:
      FLIGHT.DEPAIRPORT
  7. Now, right-click each Drop Down List component and choose
    Auto-Submit on Change from the pop-up menu. This will
    cause the page to be submitted to the server each time a new
    selection is made from any list, and will cause the appropriate
    change event handlers to be called.

  8. Drag the FLIGHT table again, but this time drop it on a
    blank spot on the page. A dialog box appears. Choose the radio
    button for creating a flightRowSet in the page bean, and click OK.

    I chose
    to put the other queries in the session bean because I didn’t want
    to lose the query data everytime the page is submitted. As the detail
    data pretty much changes on each submission, I am choosing
    to put
    this rowset in the page bean.

  9. In the Outline window, double-click the SessionBean1 > tripRowSet
    node to open it in the Query Editor. In the Query Editor, right-click
    on the PERSONID cell in the first column and choose Add Query
    Criteria. Select the Parameter radio button, click OK and close
    the Query Editor.

  10. Do the same for the flightRowSet, but add the query criteria
    for the TRIPID. Close the Query Editor.

  11. Now, double-click the flightRowSet in the page bean, add
    query criteria for FLIGHTID, and close the Query Editor.

    This query is for the detail data.

  12. Display the page in the Visual Designer (it should be
    displayed already), and click Java to
    switch to the source editor.

  13. Add the following code to the bottom, just before the final
    end brace:

    public void initFlightDropDown() {
    try {
    tripDataProvider.cursorFirst();
    getSessionBean1().getFlightRowSet().setObject(
    1, tripDataProvider.getValue("TRIP.TRIPID"));
    flightDataProvider.refresh();
    } catch (Exception e) {
    error("Cannot switch to trip " +
    tripDataProvider.getValue("TRIP.TRIPID"));
    log("Cannot switch to person " +
    tripDataProvider.getValue("TRIP.TRIPID"), e);
    }
    }
    public void initFlightDetail() {
    try {
    flightDataProvider.cursorFirst();
    flightRowSet.setObject(
    1, flightDataProvider.getValue("FLIGHT.FLIGHTID"));
    flightDataProvider.refresh();
    } catch (Exception e) {
    error("Cannot switch to flight " +
    flightDataProvider.getValue("FLIGHT.FLIGHTID"));
    log("Cannot switch to flight " +
    flightDataProvider.getValue("FLIGHT.FLIGHTID"), e);
    }
    }
    
  14. Add the following code shown in bold to the prerender
    method:

    public void prerender() {
    if ( personDD.getSelected() == null ) {
    try {
    personDataProvider.cursorFirst();
    getSessionBean1().getTripRowSet().setObject(
    1, personDataProvider.getValue("PERSON.PERSONID"));
    tripDataProvider.refresh();
    } catch (Exception e) {
    error("Cannot switch to person " +
    personDataProvider.getValue("PERSON.PERSONID"));
    log("Cannot switch to person " +
    personDataProvider.getValue("PERSON.PERSONID"), e);
    }
    initFlightDropDown();
    initFlightDetail();
    } else {
    try {
    // Synchronize data providers with current selections
    personDataProvider.setCursorRow(
    personDataProvider.findFirst(
    "PERSON.PERSONID", personDD.getSelected()));
    tripDataProvider.setCursorRow(
    tripDataProvider.findFirst(
    "TRIP.TRIPID", tripDD.getSelected()));
    flightDataProvider.setCursorRow(
    flightDataProvider.findFirst(
    "FLIGHT.FLIGHTID", flightDD.getSelected()));
    } catch (Exception e) {
    error("Cannot switch to selections");
    log("Cannot switch to selections", e);
    }
    }
    }
    
  15. Click Design in the editing toolbar to switch to the In the Visual Designer.
  16. Double-click the personDD Drop Down component (the top one)
    to cause the IDE
    to add a process value change handler for the component. The IDE
    switches to the added code. Add the following code shown in bold
    to the method:

    public void personDD_processValueChange(ValueChangeEvent event) {
    try {
    getSessionBean1().getTripRowSet().setObject(
    1, personDD.getSelected());
    tripDataProvider.refresh();
    } catch (Exception e) {
    error("Cannot switch to person " +
    personDataProvider.getValue(
    "PERSON.PERSONID"));
    log("Cannot switch to person " +
    personDataProvider.getValue(
    "PERSON.PERSONID"), e);
    }
    initFlightDropDown();
    initFlightDetail();
    }
    
  17. Click Design to switch back to the Visual Designer, double-click
    the tripDD Drop Down List component (the middle one)
    to create its change event
    handler, and add Add the following code shown in bold
    to the method:

    public void tripDD_processValueChange(ValueChangeEvent event) {
    try {
    getSessionBean1().getFlightRowSet().setObject(
    1, tripDD.getSelected());
    flightDataProvider.refresh();
    } catch (Exception e) {
    error("Cannot switch to trip " +
    tripDataProvider.getValue(
    "TRIP.TRIPID"));
    log("Cannot switch to trip " +
    tripDataProvider.getValue(
    "TRIP.TRIPID"), e);
    }
    initFlightDetail();  
    }
    
  18. Click Design one more time and double-click the flightDD
    Drop Down List component (the bottom one).
    Add the following code shown in bold
    the change event handler:

    public void flightDD_processValueChange(ValueChangeEvent event) {
    try {
    flightRowSet.setObject(
    1, flightDD.getSelected());
    flightDataProvider1.refresh();
    } catch (Exception e) {
    error("Cannot switch to flight " +
    flightDataProvider.getValue(
    "FLIGHT.FLIGHTID"));
    log("Cannot switch to flight " +
    flightDataProvider.getValue(
    "FLIGHT.FLIGHTID"), e);
    } 
    }
    
  19. Take a look at the code you have added. The code
    in the prerender method first handles the case where
    the user first lands on the page and nothing has been selected.
    It seeds the drop-down lists with the first record from the PERSON
    query and synchronizes queries for the nested detail drop-down lists and
    the detail data. If there is a selected person, it synchronizes
    the cursor positions in the queries with the drop-down list selections.

    The change event handlers synchronize the appropriate detail queries.
    A change in PERSON selection refreshes the trip, flights, and flight
    detial queries. A change in TRIP selection refreshes the flights and flight
    detail queries, and a change in FLIGHT selection refreshes the
    flight detail query.

  20. The last thing we need to do is to display some detail information.
    Click Design to display the page and, in the Outline window, expand
    propertySheet1, expand section1, and select property1 (you can also
    select the property1 in the Visual Designer, but I find it easier
    to work with the property sheet in the Outline window).

  21. In the Properties window, change the label property
    to Airline:.

  22. Drop a Static Text component on property1 in the Outline window.
  23. Expand property1, right-click staticText1, and choose Bind
    to Data.

  24. Choose flightDataProvider1 (not flightDataProvider) from
    the drop-down list, select FLIGHT.AIRLINENAME, and click OK.

  25. If you want, you can add more Property components
    to the Property Sheet Section,
    add Static Text components to the Property components, and bind the
    Static Text components
    to other columns in the database table, as I did in the above
    screenshot.

  26. Now you are ready to click Run Main Project and test your coordinated drop-downs.

Missing Image Bug

I just finished writing a NetBeans Visual Web Pack version of the JasperReports tutorial Generating Reports and PDFs From a Web Application. The NetBeans version should appear on the portal sometime
today.

While working on this tutorial, I came across a bug that prevented the company logo from appearing in the HTML output when the application is deployed to version 9 of the Sun Java System Application Server. The bug happens when you request binary data through the FacesServlet, and the fix is in for version 9.1. Ryan and Craig were the engineers who figured out why the problem was happening. They both pointed out to me that the following statement in my code sample, which sets a relative url, is not recommended:

exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, "image?image=");

The above statement results in following HTML:


http://localhost:8080/TravelReport/faces/image?image=img_0_0_0

By using the relative URL, I was needlessly incurring, for a non-JavaServer Faces entity, the extra overhead that is associated with a JavaServer Faces request. It is better to serve up the image directly, instead of going through the JavaServer Faces lifecycle.

I am pushing out a new version of the Java Studio Creator tutorial today, which shows the
correct way to pass the url (which happens to work with Sun Java Application Server 9):

exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI,
request.getContextPath() + "/image?image=");

While we are talking about server bugs, a customer wrote to me that they were getting
a java.lang.NullPointerException from the
javax.faces.component.UIComponentBase class’s getRenderer method
whenever they use the Table component in web applications deployed to JBoss.
This is a known bug, and is documented in the Release Notes. What is happening
is that when you create a Visual Web project, the classpath on the container is checked.
If the IDE finds a MyFaces implementation, it gives the MyFaces implementation precedence over the
JavaServer Faces Reference Implementation libraries. To prevent this problem from happening,
delete or move the JBOSS_HOME/server/default/deploy/jbossweb-tomcat55.sar/jsf-lib directory before you create the Visual
Web Pack project for that container. This forces the the IDE to bundle the JSF Reference Implementation with the project.

To go back to using the MyFaces run time for running non-Visual Web Pack based applications,
follow these steps:

  1. In the Projects window, right-click the Libraries node and choose Add Library.
  2. In the Add Library dialog box, select the desired MyFaces binaries.
  3. Click Add Library.
  4. Make sure the JSF-RI libraries are not deployed.
  5. Modify web.xml to include the following:
  6. <listener>
    <listener-class>
    org.apache.myfaces.webapp.StartupServletContextListener
    </listener-class>
    </listener>
    

Workaround for Button Component Viewed in IE7

When a web page that includes the Web UI Button component is viewed by the Internet Explorer 7 browser, the button component might be rendered with an incorrect width.
This problem occurs when the Button component is placed on the page using absolute positioning.

You can use either of the following workarounds to solve this problem.

  • Specify the width property for the button, or resize the button in the Visual Designer to make the IDE assign a width to the button.
  • In the Visual Designer, nest the Button component inside a Group Panel component. By doing this, you move the absolute positioning from the button to the panel, outside the button.
  • topic:[Button]

Using the Object Array Data Provider

A forum poster recently asked for the following information:

I have a table with 5 columns, (week_no, objective, date1, date2 and add report).
How do I get the date for date1( example, today’s date)? How do I set the week number as auto increment by 1( example, row 1, the week_no is 1, row 2, the week_no is 2 and so on)? Lastly, how to I set the add report button to link to another JavaServer Pages file?

This scenario gives me an excellent opportunity to show how
to use an Object Array Data Provider (OADP). I usually use the
Object List Data Provider (OLDP), but OLDPs take a bit
more work. (See the Using Hibernate tutorial for an
OLDP example.) If you have a simple array of data, the OADP
might be the better choice, as in this case. The following steps create
a table similar to the one requested in the forum.

  1. Create a web application named ArrayTableExample.

    (If using the Visual Web Pack, be sure to create a Visual Web Application.)

  2. Create a JavaBeans object for the array. In this example,
    I chose to put the week number, start date, and end date in the
    bean. In the Projects window, right-click
    Source Packages > arraytableexample, choose New > Java Class,
    name the class WeekBean, and click Finish.

  3. Replace the class definition with the following code shown in bold.
    /*
    * WeekBean.java
    *
    */
    package arraytableexample;
    public class WeekBean
    extends Object implements Serializable {
    private int weekNumber;
    private Calendar startDate;
    private Calendar endDate;
    private int dayOfWeek;
    public WeekBean(int weekNumber) {
    this.weekNumber = weekNumber;
    Calendar workingDate = Calendar.getInstance();
    workingDate.set(java.util.Calendar.HOUR_OF_DAY, 0);
    int offset = weekNumber - 1;
    workingDate.add(
    Calendar.DAY_OF_YEAR,
    + (offset * 7));
    dayOfWeek = workingDate.get(Calendar.DAY_OF_WEEK);
    startDate = (Calendar) workingDate.clone();
    startDate.add(
    Calendar.DAY_OF_YEAR, - (dayOfWeek - Calendar.SUNDAY));
    endDate = (Calendar) workingDate.clone();
    endDate.add(
    Calendar.DAY_OF_YEAR,
    + (Calendar.SATURDAY - dayOfWeek));
    }
    public WeekBean() {
    this(1);
    }
    public int getWeekNumber() {
    return this.weekNumber;
    }
    public void setWeekNumber(int weekNumber) {
    this.weekNumber = weekNumber;
    }
    public Calendar getStartDate() {
    return this.startDate;
    }
    public void setStartDate(Calendar startDate) {
    this.startDate = startDate;
    }
    public Calendar getEndDate() {
    return endDate;
    }
    public void setEndDate(Calendar endDate) {
    this.endDate = endDate;
    }
    }
    
  4. Right-click in the code and choose Fix Imports. Make sure the
    Fully Qualified Name for Calendar is java.util.Calendar, and click OK.

  5. Close and save the file.
  6. In this example, we want the table to show the same
    data throughout the session, so put the array property
    in the session bean. In the Projects window, double-click the Session Bean node to open SessionBean1.java in the source editor.

  7. Add the following code to the bottom of the class defintion,
    just before the ending brace. This code also adds properties
    for passing the selected start and end dates to other pages.

    
    /**
    * Holds value of property weeks.
    */
    WeekBean[] weeks = {
    new WeekBean(1),
    new WeekBean(2),
    new WeekBean(3),
    new WeekBean(4)
    };
    /**
    * Getter for property weeks.
    * @return Value of property weeks.
    */
    public WeekBean[] getWeeks() {
    return this.weeks;
    }
    /**
    * Holds value of property reportStartDate.
    */
    private Calendar reportStartDate;
    /**
    * Getter for property reportStartDate.
    * @return Value of property reportStartDate.
    */
    public Calendar getReportStartDate() {
    return this.reportStartDate;
    }
    /**
    * Setter for property reportStartDate.
    * @param reportStartDate New value of property reportStartDate.
    */
    public void setReportStartDate(Calendar reportStartDate) {
    this.reportStartDate = reportStartDate;
    }
    /**
    * Holds value of property reportEndDate.
    */
    private Calendar reportEndDate;
    /**
    * Getter for property reportEndDate.
    * @return Value of property reportEndDate.
    */
    public Calendar getReportEndDate() {
    return this.reportEndDate;
    }
    /**
    * Setter for property reportEndDate.
    * @param reportEndDate New value of property reportEndDate.
    */
    public void setReportEndDate(Calendar reportEndDate) {
    this.reportEndDate = reportEndDate;
    }
    
  8. Right-click in the code and choose Fix Imports. Make sure the
    Fully Qualified Name for Calendar is java.util.Calendar, and click OK.

  9. Close and save SessionBean1.java.
  10. View Page1 in the Visual Designer.
  11. In the Palette, expand the Data Providers section.
  12. Drag the Object Array Data Provider node and drop it on Page1.
  13. If the properties for the OADP do not appear in the Properties
    window, select Page1 > objectArrayDataProvider1 in the Outline
    window to make its properties appear.

  14. In the Properties window, change the id to weekDataProvider.
  15. Here is where it starts getting kludgy. You should be able to
    choose weeks from the array drop-down list, but
    it propably is not appearing at this point. If weeks is
    not in the drop-down list, choose Clean and
    Build Main Project from the main menu. After the build
    completes, close and reopen the project.

  16. In the Outline window, select Page1 > weekDataProvider.
  17. In the Properties window, select weeks (SessionBean1) from
    the array drop-down list.

  18. Drag a Table component from the Palette and drop it on
    Page1.

  19. Right-click the Table component and choose Table Layout.
  20. In the Table Layout dialog box, choose weekDataProvider
    from the Get Table From drop-down list.

  21. Use the Up and Down buttons to put the values in the
    Selected list in the following order:

    weekNumber
    startDate
    endDate
    
  22. (Optional) Set the Header Text values for the columns
    to Week, Start Date, and End Date.

  23. Click New to add another column.
  24. In the new column, set the Header Text to blank, select Button from the Component Type drop-down list, and
    set the Value Expression to Show Me.

  25. Click OK to dismiss the dialog box.

    Again, it gets kludgy. Only one row appears, which says "No items found", and there is no button. Don't worry, it will work out
    in the end.

  26. In the Outline window, expand table1 > tableRowGroup1 > tableColumn4,
    right-click button1, and choose Edit Action Event Handler.

    Page1.java opens in the source editor and scrolls to the newly
    added button1_action method.

  27. Add the code shown in bold to the method.
    public String button1_action() {
    getSessionBean1().setReportStartDate(
    (Calendar)getValue("#{currentRow.value['startDate']}"));
    getSessionBean1().setReportEndDate(
    (Calendar)getValue("#{currentRow.value['endDate']}"));
    return null;
    }
    
  28. Right-click in the code and choose Fix Imports. Make sure the
    Fully Qualified Name for Calendar is java.util.Calendar, and click OK.

  29. Typically, you would set up page navigation to go to
    another page to display the report. For simplicity, click Design
    and drop
    a Static Text component on the page to display the
    selected start date.

  30. Right-click the Static Text component and choose Bind to Data.
  31. Click Bind to an Object, select SessionBean1 >
    reportStartDate, and click OK.

  32. Click Run Main Project. When the page appears, click the
    button in each row to verify that the action method returns
    the right value.

Winston has many blog entries about the dataprovider. A good place to start is his blog titled What is this Data Provider in Sun Java Studio Creator anyway?. Another good resource is Joel Brown's Weblog.

topic:[jsf]
topic:[netbeans]
topic:[creator]
topic:[dataprovider]