ObjectListDataProvider Tutorial

This is a tutorial for using the ObjectListDataProvider in a Visual Web Project. A ObjectListDataProvider is useful if the underlaying data is from a datasource not supported by NetBeans. Some samples for such datasources are a JPA or hibernate connection, other legacy systems such SAP or Lotus Notes and files in various formats.

In this tutorial we use a text file with customer records as datasource for our application.

Creating the project

In the first step you create a normal VWP project named OldpSample:

Project settings OLDP

Address POJO

For data storage we use a simple POJO object. Right click the oldpsample package under «Source Packages» and select «New -> Java Class». Name the class Address.

Create Address class

package oldpsample;

public class Address {

  private String id;
  private String title;
  private String lastname;
  private String firstname;
  private String street;
  private String city;
  private String state;
  private String country;

/** Creates a new instance of Address */
  public Address() {
  }

  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public String getLastname() {
    return lastname;
  }

  public void setLastname(String lastname) {
    this.lastname = lastname;
  }

  public String getFirstname() {
    return firstname;
  }

  public void setFirstname(String firstname) {
    this.firstname = firstname;
  }

  public String getStreet() {
    return street;
  }

  public void setStreet(String street) {
    this.street = street;
  }

  public String getCity() {
    return city;
  }

  public void setCity(String city) {
    this.city = city;
  }

  public String getState() {
    return state;
  }

  public void setState(String state) {
    this.state = state;
  }

  public String getCountry() {
    return country;
  }

  public void setCountry(String country) {
    this.country = country;
  }

}

Create AddressDataProvider

Now we create the class AddressDataProvider. We create a new class and derive it from ObjectListDataProvider. Right click the oldpsample package under «Source Packages» and select «New -> Java Class».

Create AdressDataProvider class

Our class stores all data in a ArrayList, so we need a member variable of type ArrayList. In the constructor we must tell the underlying ObjectListDataProvider where the data comes from (method setList) and of which type the data is (method setObjectType). We also need methods to load the data from file or stream.

package oldpsample;

import com.sun.data.provider.impl.ObjectListDataProvider;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class AddressDataProvider extends ObjectListDataProvider {

  private ArrayList addressList = new ArrayList();

  /** Creates a new instance of AddressDataProvider */
  public AddressDataProvider() {
    setList( addressList );
    setObjectType( Address.class );
  }

  public void load(InputStream istream ) {
      try {
      InputStreamReader sr = new InputStreamReader( istream );
      BufferedReader br = new BufferedReader( sr );

      while ( br.ready() ) {
        String line = br.readLine();
        String[] cols = line.split( ";" );

        if ( cols.length == 8 ) {
          Address address = new Address();
          address.setId( cols[0] );
          address.setTitle( cols[1] );
          address.setLastname( cols[2] );
          address.setFirstname( cols[3] );
          address.setStreet( cols[4] );
          address.setCity( cols[5] );
          address.setState( cols[6] );
          address.setCountry( cols[7] );
          getList().add( address );
        }
      }

    } catch ( Exception e ) {
      e.printStackTrace();
    }
  }

  public void load(String filename) {
    try {
      FileInputStream fs = new FileInputStream( filename );
      load( fs );
    } catch ( Exception e ) {
      e.printStackTrace();
    }
  }

}

Add AddressDataProvider to SessionBean1

In the outline view right click on SessionBean1 and select «Add->Property» from the context menu. Name the property «addressDataProvider» and enter «AddressDataProvider» as Type. Leave all other options on the default values.

New Property addressDataProvider

Double click SessionBean1 in the outline view. Find the line

private AddressDataProvider addressDataProvider;

and change it to

private AddressDataProvider addressDataProvider = new AddressDataProvider();

You must build, close and reopen your VWP project now (as of NetBeans 5.5.1). If not, NetBeans doesn’t detect our ObjectListDataProvider. This should hopefully not been necessary in future NetBeans releases.

Design Web Page

The project wizard has generated a default web page Page1.jsp. Open this page and the visual designer starts.

Select a table component from the palette and drop it onto your page. Right click the table component and select «Bind to Data…». Select «addressDataProvider (SessionBean1)» from the dropdown list. Reorder the fields with the «Up» and «Down» buttons, so it look like this:

Select Data Provider

Press «OK» and our page has a table component bound to the AddressDataProvider.

To show some data in the table component we let the user upload a CSV file. Drop a File Upload and a Button component from the palette onto the page. Set the text property of the button to «Upload file». Your page should look like this:

Page Design

Double click on the «Upload file» button and enter the following code into the event handler:

public String button1_action() {
  if ( fileUpload1.getUploadedFile().getSize() > 0 ) {
    try {
      getSessionBean1().getAddressDataProvider().load(
        getFileUpload1().getUploadedFile().getInputStream() );
    } catch ( Exception e ) {
      e.printStackTrace();
    }
  }
  return null;
}

Run your project. Use this sample CSV data file to test the application:

1;Mr.;Able;Tony;216 King St;San Francisco;CA;USA
2;Mr.;Black;Tom;655 Divisadero St;San Francisco;CA;USA
3;Mr.;Kent;Richard;509 Valencia St;San Francisco;CA;USA
4;Mr.;Chen;Larry;407 Ellis St;San Francisco;CA;USA
5;Mrs.;Donaldson;Sue;314 Columbus Ave;San Francisco;CA;USA
6;Mr.;Murrell;Tony;4124 Geary Blvd;San Francisco;CA;USA

This sample project can also be downloaded.

Fill a treeview programmatically

You must build a collection of TreeNode objects and add this collection to the TreeView control. Each TreeNode object has several properties to set up the visual appearance and functionality.

Important TreeNode properties

expanded - Shows this node expaned with children
ext - Title text of the node
target - Target browser window
toolTip - Tooltip text to display
url - Hyperlink to navigate to
action - Name of method to call if user selects this node
actionListenerExpression - Expression for action listener method.

Adding icon to TreeNode

To add a icon to the TreeNode you must first create a ImageComponent. Now you can set the theme specific icon with the setIcon method. Use a constant of class ThemeImages for the icon name. Add the created ImageComponent as facet to the TreeNode.

Sample:

ImageComponent image = new ImageComponent();
image.setIcon( TreeImages.TREE_FOLDER );
treeNode.getFacets().put( treeNode.IMAGE_FACET_KEY, image );

Setting Action Expression for TreeNode

To set the Action Expression of a TreeNode you must use the method setActionExpression of the TreeNode object. This method needs a MethodExpression object as parameter.

Sample code:

ExpressionFactory ef = FacesContext.
  getCurrentInstance().
  getApplication().
  getExpressionFactory();
ELContext elContext = FacesContext.
  getCurrentInstance().
  getELContext();
MethodExpression me = ef.createMethodExpression(
  elContext,
  "#{Page1.treeNode_action}",
  String.class, new Class[]{} );
treeNode.setActionExpression( me );

ICEFaces installation for NetBeans IDE

ICEFaces is a Java Server Faces component library. To integrate ICEFaces into the NetBeans IDE and the Visual Web Pack the following steps are necessary.

Download of ICEFaces components

The following downloads from the ICEFaces website are needed:

  • ICEfaces-<version>-libs-NetBeans.zip
  • ICEfaces-NetBeans-IDE-<version>.zip
  • ICEfaces-<version>-complib-NetBeans.zip

Installation of ICEFaces runtime library

Unpack the file ICEfaces-<version>-libs-NetBeans.zip and import the included com-icesoft-ide-netbeans-libs-module.nbm module with the NetBeans Update Manager.

Installation of ICEFaces IDE integration

Unpack the file ICEfaces-NetBeans-IDE-<version>.zip and install the module com-icesoft-faces-vwp-ide.nbm. This module must also be installed with the NetBeans Update Manager.

Installation of ICEFaces component library

Unpack file icefaces-webui.complib from ICEfaces-<version>-complib-NetBeans.zip and copy it to your <netbeans-install-dir>/rave2.0/samples folder.

Import the component library with the Component Library Manager under «Tools->Component Library Manager» into your IDE.

Use of ICEFaces components in a Visual Web Pack project

To use the ICEFaces components in a Visual Web Pack application you must add the ICEFaces Component Suite to your project.

Using Jasper Reports with Visual Web Pack

This tutorial illustrates the use of Jasper Reports with a Visual Web Pack application.

Register Jasper Reports library

Use the NetBeans Library Manager to create a library for the Jasper Reports class libraries. You need at least the following files from the distribution:

  • dist/jasperreports-<version>.jar
  • lib/commons-beanutils-1.7.jar
  • lib/commons-collections-2.1.jar
  • lib/commons-digester-1.7.jar
  • lib/commons-logging-1.0.2.jar
  • lib/itext-1.3.1.jar

Register Jasper Reports image servlet

The image servlet is needed if you want html rendered reports (also without any graphical elements, because report placeholders uses images from this servlet). So you must register it in the web.xml configuration file. You can use the NetBeans web.xml editor to do so.

Servlet name  : ImageServlet
Servlet class : net.sf.jasperreports.j2ee.servlets.ImageServlet
URL           : /image

Insert methods for report output to application bean

The following methods in the application bean can be used to output a precompiled report as html or pdf. In this sample a collection of java objects is used as data source. For other data sources see the Jasper Reports documentation.

/**
 * Output Jasper Report
 *
 * @param filename Precompiled report filename
 * @param type Content type of report ("application/pdf" or "text/html")
 * @param data Collection of value objects
 */
public void jasperReport( String filename, String type, Collection data ) {
  jasperReport( filename, type, data, new HashMap() );
}

/**
 * Output Jasper Report
 *
 * @param filename Precompiled report filename
 * @param type Type of report ("application/pdf" or "text/html")
 * @param data Collection of value objects
 * @param params Map with parameters
 */
public void jasperReport( String filename, String type, Collection data, Map params ) {
  final String[] VALID_TYPES = { "text/html", "application/pdf" };
  // First check if type is supported
  boolean found = false;
  for ( int i = 0; i < VALID_TYPES.length; i++ ) {
    if ( VALID_TYPES[i].equals( type ) ) {
      found = true;
      break;
    }
  }

  if ( !found ) {
    throw new IllegalArgumentException( "Report type '" + type + "' not supported." );
  }

  // InputStream for compiled report
  ExternalContext econtext = getExternalContext();
  InputStream stream = econtext.getResourceAsStream( filename );

  if ( stream == null ) {
    throw new IllegalArgumentException( "Report '" + filename + "' could not be opened." );
  }

  // Use collection as data source
  JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource( data );
  JasperPrint jasperPrint = null;

  try {
    jasperPrint = JasperFillManager.fillReport( stream, params, ds );
  } catch ( RuntimeException e ) {
    throw e;
  } catch ( Exception e ) {
    throw new FacesException( e );
  } finally {
    try {
      stream.close();
    } catch ( IOException e ) {
    }
  }

  // Configure exporter and set parameters
  JRExporter exporter = null;
  HttpServletResponse response = (HttpServletResponse) econtext.getResponse();
  FacesContext fcontext = FacesContext.getCurrentInstance();

  try {
    response.setContentType( type );

    if ( "application/pdf".equals( type ) ) {
      exporter = new JRPdfExporter();
      exporter.setParameter( JRExporterParameter.JASPER_PRINT, jasperPrint );
      exporter.setParameter( JRExporterParameter.OUTPUT_STREAM,
        response.getOutputStream() );
    } else if ( "text/html".equals( type ) ) {
      exporter = new JRHtmlExporter();
      exporter.setParameter( JRExporterParameter.JASPER_PRINT, jasperPrint );
      exporter.setParameter( JRExporterParameter.OUTPUT_WRITER, response.getWriter() );
      HttpServletRequest request = (HttpServletRequest)
        fcontext.getExternalContext().getRequest();
      request.getSession().setAttribute(
        ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint );
      exporter.setParameter( JRHtmlExporterParameter.IMAGES_MAP, new HashMap() );
      exporter.setParameter(
        JRHtmlExporterParameter.IMAGES_URI,
        request.getContextPath() + "/image?image=" );
    }
  } catch ( RuntimeException e ) {
    throw e;
  } catch ( Exception e ) {
    throw new FacesException( e );
  }

  // Export report
  try {
    exporter.exportReport();
  } catch ( RuntimeException e ) {
    throw e;
  } catch ( Exception e ) {
    throw new FacesException( e );
  }

  // Tell JavaServer faces that no more processing is necessary
  fcontext.responseComplete();
}

Start report output from page bean

The output of a report can initiated from a ActionEvent with the following code:

try {
  getApplicationBean().jasperReport(
    "/reports/report.jasper",
    "application/pdf",
    getSessionBean().getSuchergebnisDataProvider().getList() );
} catch ( Exception e ) {
  Logger.getLogger(getClass().getName()).severe( e.getMessage() );
}

return null;

Center VWP components

There isn’t any standard function in the Visual Web Pack to center components on the page. You can only use absolute or flow layout.

If you want center your components horizontally or vertically, you need CSS. This is done with the style setting of your component.

position: absolute;
left: 50%;
top: 50%;

This setting would center the left upper corner of your component on the page, but not the whole component. To center the whole component you must adjust the margins. The margins can be negative, so substract the half of the vertical and horizontal size from the corresponding margin. In this sample assume that the component has a height of 100 pixels and a width of 200 pixels.

position: absolute;
left: 50%;
top: 50%;
margin-top: -50px;
margin-left: -100px;