PrimeFaces Nightly Builds

Good news to PrimeFaces community! I’ve spent quite some time on my ubuntu vps and finally managed to setup hudson to build PrimeFaces artifacts on a daily basis. In addition to UI Components, sample applications including component showcase, phonebook (seam-jpa) and moviecollector (spring-jpa) are also deployed to Prime Technology repository every day with sources included. Download page is updated on PrimeFaces homepage to reflect changes as well. Also PrimeFaces community has read only access to hudsonto monitor builds and the progress.

PrimeFaces goes JSF 2.0

PrimeFaces team is pleased to announce that PrimeFaces 2.0.0.RC is released, this initial release is the port of 1.0.0.RC targeting JSF 2.0. You can download the release from downloads section and reference documentation is updated to cover this release.

So which JSF 2.0 features does PrimeFaces use? Currently state management is migrated to new state management infrastructure of JSF 2.0 which performs much better compared to JSF 1.x. We still keep our Resource Servlet and decided not to migrate to JSF 2.0 resource loading for now since current solution is optimized for PrimeFaces. Also our jquery based ajax solution is still in instead of JSF 2.0 ajax.

In future PrimeFaces 2.x releases we’ll consider moving more features to use JSF 2.0 stuff for sure but right now the priority is to make sure PrimeFaces 2.x runs smoothly on JSF 2.0. Also from now on there’ll be two branches; PrimeFaces 1.x and PrimeFaces 2.x, which will be developed and released in sync.

PrimeFaces 1.0.0.RC is Released

I’m pleased to announce that PrimeFaces 1.0.0.RC is released.

PrimeFaces 1.0.0.RC introduces 12 new components, Ajax Push Alpha Integration, various improvements and fixes. In total 61 issues in tracker are closed.

  • Alpha Ajax Push/Comet integration built on top of Atmosphere Framework.
  • New component: AccordionPanel (Reimplementation)
  • New component: Password Strength
  • New component: Inplace
  • New component: Terminal
  • New component: Printer
  • New component: Tabslider
  • New component: Breadcrumb
  • New component: Messages
  • New component: Message
  • New component: RemoteCommand
  • New component: Resource
  • New component: Watermark
  • TouchFaces enhancements; exposed client side api, new view animations.
  • DataTable enhancements; Instant Ajax row selection and Ajax Sorting
  • Many improvements and fixes to issues reported by PrimeFaces community

See the full changelog for detailed information. Also don’t forget to update your Reference Documentation, it has reached 300 pages now.

Note: This version is not backward compatible, please see Migration Guide.

Next release is for PrimeFaces 2.0.0.RC that targets JSF 2.0, we’re aiming to release 2.0.RC by next week. After that we’ll add more components such as treeTable, contextMenu, fullCalendar, implement feature requests of PrimeFaces users and improve the current codebase.

Thanks to everyone supporting PrimeFaces!

By the way today is the 1st birthday of PrimeFaces, happy birthday!

Mobile GPS Navigation App with JSF

I’ve created various sample mobile apps before such as Translator, Weather, News, Notes, Twitter Client and Mobile Chat (powered by PrimeFaces/Atmosphere Push infastructre) etc. Since these are webapps tuned for mobile app look and feel, I was wondering the limits of a mobile webapp compared to a native app. Geolocation and GPS support might sound like one of these limitations but well, it is not :) As a proof of concept for a PrimeFaces/TouchFaces app I’ve created the PathFinder, A mobile GPS Navigation app for iphone.

To begin with here’s the final output; There’re two screens, one is for map with directions and other is for settings. Click images for higher resolution.

pf1 pf1 pf1

See it in action

I’ve recorded a short screencast as well running the PathFinder on iPhone Emulator.

All of this is basically a simple JSF page; pathfinder.jsf

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<f:view xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:p="http://primefaces.prime.com.tr/ui"
	xmlns:i="http://primefaces.prime.com.tr/touch"
	contentType="text/html">

	<i:application icon="/images/touch/mapicon.png">
		<f:facet name="meta">
			<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=true&amp;key=ABQIAAAAfC5eyG3CuuRKtsMbGj42fhThrJrTqAJnkzhJQxjbFhIXTdSD6xRglAovT0AWB71tfpSZxEd9pJoxwQ" type="text/javascript"></script>
			<script type="text/javascript">

				PathFinder = {

						init : function() {
							map = new GMap2(document.getElementById("map"));
							map.setUIToDefault();

				        	navigator.geolocation.getCurrentPosition(
						        function(position) {
							        lat = position.coords.latitude;
							        lng = position.coords.longitude;
							        var center = new GLatLng(position.coords.latitude, position.coords.longitude);
							        map.setCenter(center, 15);
							        map.addOverlay(new GMarker(center));
							        geocoder = new GClientGeocoder();
							        directions = new GDirections(map, document.getElementById('route'));
						        });
						},

						findAndGo : function() {
							var address = document.getElementById('address').value;
							geocoder.getLatLng(address,function(point) {
								 if (!point) {
						              alert(address + " not found");
						          } else {
						              directions.load("from " + lat + " " + lng + " to " + point.lat() + " " + point.lng());
						           }
							});
						}
					};

				if(!navigator.geolocation) {
					alert('Error: PathFinder requires a GPS capable device.');
				} else {
					window.onload = PathFinder.init;
				}

			</script>
			<meta content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" name="cube"/>
		</f:facet>

		<i:view id="home" title="PathFinder">
			<f:facet name="rightNavBar">
				<i:navBarControl label="Settings" view="settings" type="button" effect="cube"/>
			</f:facet>

			<h:form prependId="false">
				<i:tableView>
					<i:rowGroup display="edgetoedge">
						<div id="map" style="width:100%;height:285px;"></div>
					</i:rowGroup>

					<i:rowGroup>
						<i:rowItem>
							<h:inputText id="address"/>
						</i:rowItem>
					</i:rowGroup>

					<p:commandLink style="margin:10px 10px;" styleClass="whiteButton" value="#" onclick="PathFinder.findAndGo();return false;">Find and Go!</p:commandLink>

					<i:rowGroup>
							<i:rowItem>
								<div id="route"></div>
							</i:rowItem>
					</i:rowGroup>
				</i:tableView>
			</h:form>

		</i:view>

		<i:view id="settings" title="Settings">
			<f:facet name="leftNavBar">
				<i:navBarControl label="Home" view="home" />
			</f:facet>

			<h:form prependId="false">
				<i:tableView>

					<i:rowGroup>
						<i:rowItem>
							<h:outputText value="Transport" />
							<h:selectOneMenu>
								<f:selectItem itemLabel="Driving" itemValue="d" />
								<f:selectItem itemLabel="Walking" itemValue="w" />
							</h:selectOneMenu>
						</i:rowItem>

						<i:rowItem>
							<h:outputText value="Traffic" />
							<i:switch id="traffic"/>
						</i:rowItem>
					</i:rowGroup>

				</i:tableView>

				<p:commandLink style="margin:0 10px;" styleClass="whiteButton" value="#" onclick="TouchFaces.goBack();">Save</p:commandLink>

			</h:form>

		</i:view>

	</i:application>

</f:view>

That’s just it, now you have a GPS enabled navigation app with a couple of lines. Let’s breakdown the important points to see how it works;

* GEOLocation info is provided by mobile safari, navigation geolocation api is an HTML5 feature supported by major browsers like Safari and Firefox (no IE of course). When you run the application, safari asks for a confirmation since the app tries to access hardware information and on page load places a markers on map with the geo location info.

* Once we have the location, it’s trivial to place a map and do some gmap api coding. ‘Find and Go’ button simply does a geocoding and retrieves the latitude and longitude, with that it asks gmap api for directions and updates the map. Update happens in 5 seconds with the updated geo location info.

* A settings view is also added, I left out the implementation of settings UI but it helps to demonstrate how easy it can be to create another UI for customizations.

Summary

PathFinder is a simple reference app, things can be done with PrimeFaces is limitless. For example, since PrimeFaces also supports Ajax Push, it would be so easy to create location based mobile Comet applications as well.

Finally one thing I’d like to emphasize again, what PrimeFaces has so far (70+ Ajax Components, Ajax Push/Comet, Lightweight design, TouchFaces, GPS enabled apps, …) is just the beginning.

I’m speaking at JSFSummit 09

I’ll be speaking at JSFSummit 09 in Orlando between December 1-4 with my “Rapid RIA with PrimeFaces” session. I really enjoyed last year in Washington D.C. when the conference was called JSFOne back then.

I’m really looking forward to get together again with folks like Ed Burns, my man Matthias Wessendorf, Martin Marinschek, Max Katz, Kito Mann and Andy Schwartz. It’ll be a great conference!

Mobile Twitter Client with JSF

I’ve added another sample to TouchFaces showcase applications, this one is called TwitFaces allowing to view someone’s tweets in your iphone. The app integrates with twitter rest api and created with TouchFaces mobile JSF kit of PrimeFaces.

Let’s begin with TwitterService

package org.primefaces.examples.service;

import java.util.List;

public interface TwitterService {

	public List<String> getTweets(String username);
}

And TwitterRSSService, the RSS based implementation using Rome.

package org.primefaces.examples.service;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;

public class TwitterRSSService implements TwitterService {

	private static final Logger logger = Logger.getLogger(TwitterRSSService.class.getName());

	public List<String> getTweets(String username) {
		List<String> tweets = new ArrayList<String>();

		try {
			URL feedSource = new URL("http://twitter.com/statuses/user_timeline.rss?screen_name=" + username);

			SyndFeedInput input = new SyndFeedInput();
			SyndFeed feed = input.build(new XmlReader(feedSource));
			for(Object f : feed.getEntries()) {
				SyndEntry entry = (SyndEntry) f;
				tweets.add(entry.getTitle().substring(username.length() + 2));
			}
		}catch(Exception e) {
			logger.severe(e.getMessage());
		}

		return tweets;
	}
}

And the JSF backing bean called TwitterController powered by PrimeFaces Optimus.

package org.primefaces.examples.touch;

import java.util.List;

import javax.faces.event.ActionEvent;

import org.primefaces.examples.service.TwitterService;
import org.primefaces.optimus.config.Scope;
import org.primefaces.optimus.config.annotations.Controller;

import com.google.inject.Inject;

@Controller(name="twitterController", scope=Scope.REQUEST)
public class TwitterController {

	@Inject private TwitterService twitterService;

	private String username;

	private List<String> tweets;

	public void loadTweets(ActionEvent actionEvent) {
		tweets = twitterService.getTweets(username);
	}

	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}

	public List<String> getTweets() {
		return tweets;
	}
	public void setTweets(List<String> tweets) {
		this.tweets = tweets;
	}
}

Finally create your app as a JSF page, twitfaces.xhtml;

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<f:view xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:p="http://primefaces.prime.com.tr/ui"
	xmlns:i="http://primefaces.prime.com.tr/touch"
	contentType="text/html">

	<i:application icon="/images/touch/twiticon.png">
		<i:view id="home" title="TwitFaces">
			<h:form prependId="false">
				<i:tableView>
					<i:rowGroup>
						<i:rowItem>
							<h:inputText value="#{twitterController.username}" />
						</i:rowItem>
					</i:rowGroup>

					<p:commandLink actionListener="#{twitterController.loadTweets}" style="margin:10px 10px;"
					styleClass="whiteButton" value="#" update="display">Get Tweets</p:commandLink>

					<i:rowGroup id="display">
						<ui:repeat value="#{twitterController.tweets}" var="tweet">
							<i:rowItem>
								#{tweet}
							</i:rowItem>
						</ui:repeat>
					</i:rowGroup>
				</i:tableView>
			</h:form>
		</i:view>
	</i:application>

</f:view>

That’s it running twitfaces.jsf displays;

twitfaces

TwitFaces is a very simple app, a full blown twitter client can be written on top of it easily using TouchFaces/PrimeFaces.

Online Demo

Check out TwitFaces app live on PrimeFaces Online Demos.

PrimeFaces Reorg

Two PrimeFaces modules, Optimus and FacesTrace are moved to the PrimeFaces Extensions as spin-off projects and PrimeFaces UI module is renamed as PrimeFaces

Main goal of PrimeFaces has always been to be the ultimate JSF component suite, by this change PrimeFaces became all about UI again.

Posted in Developer, Java, PrimeFaces. Comments Off

Dynamic Images with JSF

Legacy way to display binary images is to create a servlet and send the byte content as a stream. This requires a dedicated servlet and probably different servlets dealing with handling cases.

PrimeFaces features a simple but powerful StreamedContent API and p:graphicImage component to display any binary image easily. This binary image could be images stored in a database or images created programmatically on-the-fly. Following are a couple examples for demonstrating how easy it is to display binary images with PrimeFaces.

Images Stored in Database
This example retrieves a blob from a jdbc resultset and provides it’s inputstream as a StreamedContent.

public class BackingBean {

	private StreamedContent dbImage;

	public BackingBean() {
		InputStream dbStream = //Get inputstream of a blob eg javax.sql.Blob.getInputStream() API
		dbImage = new DefaultStreamedContent(dbStream, "image/jpeg");
	}

	//getters and setters
}
 <p:graphicImage value="#{backingBean.dbImage}" />

dynamicImage.jsf

Generated Chart Images
JFreeChart is a popular open source charting library, PrimeFaces also have flash based cool charts but if you want
to use JFreeChart instead you don’t need a wrapper JSF component for this. Just create your chart and define it as
as a streamed content.

public class BackingBean {

	private StreamedContent chartImage;

	public BackingBean() {
		try {
			JFreeChart jfreechart = ChartFactory.createPieChart("Turkish Cities", createDataset(), true, true, false);
			File chartFile = new File("dynamichart");
			ChartUtilities.saveChartAsPNG(chartFile, jfreechart, 375, 300);
			chartImage = new DefaultStreamedContent(new FileInputStream(chartFile), "image/png");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private PieDataset createDataset() {
		DefaultPieDataset dataset = new DefaultPieDataset();
		dataset.setValue("Istanbul", new Double(45.0));
		dataset.setValue("Ankara", new Double(15.0));
		dataset.setValue("Izmir", new Double(25.2));
		dataset.setValue("Antalya", new Double(14.8));

		return dataset;
	}

	//getters and setters
}
 <p:graphicImage value="#{backingBean.chartImage}" />

This chart example truly demonstrates the power of PrimeFaces StreamedContent, I’ve created a JSFChartCreator component long time ago which became quite popular in JSF community. The problem was when you wrap a huge API like JFreeChart, flexibility gets lost since it’s just too hard to support every different setting in JFreechart API with a wrapper component. StreamedContent and p:graphicImage simply makes any other JSF component wrapping JFreeChart obselete. Instead with this way you still have the full power of chart api and a very easy way to display it.

dynamicImage.jsf

Runtime Barcode Creator
Similar to the chart example, an on-the-fly generated barcode can easily be presented. This example uses barbecue project to create barcodes.

public class BackingBean {

	private StreamedContent barcode;

	public BackingBean() {
		try {
			File barcodeFile = new File("dynamicbarcode");
			BarcodeImageHandler.saveJPEG(BarcodeFactory.createCode128("PRIMEFACES"), barcodeFile);
			barcode = new DefaultStreamedContent(new FileInputStream(barcodeFile), "image/jpeg");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	//getters and setters
}
 <p:graphicImage value="#{backingBean.barcode}" />

dynamicImage-1.jsf

Online Demo
Examples I’ve given here are also available live at PrimeFaces Showcase.

Summary
One of the design principles behind PrimeFaces is to hide complexity and keep the flexibility, this is just one example of it in PrimeFaces.

Primus RC Trailer

Posted in Developer, Java, PrimeFaces. Comments Off

Web Based Ajax Terminal

PrimeFaces brings desktop terminals to the web, p:terminal is an ajax powered JSF component to execute commands defined on server side. Usage is very simple, just place the terminal and provide a command handler.

Screen shot 2009-10-20 at 8.47.11 PMCode

    <p:terminal commandHandler="#{mybean.handleCommand}" />

CommandHandler is a simple java method taking two parameters, first one is the name of the command and second parameter is an array of command arguments.

    public String handleCommand(String command, String[] params) {
		if(command.equals("greet"))
			return "Hello" + params[0];
		else if(command.equals("date"))
			return new Date().toString();
		else
			return command + " " + not found;
	}

Terminal in Mock OS X
I’ve integrated terminal to famous PrimeFaces Mock OS X, there’s a terminal icon in the dock displaying the terminal in a dialog. Check out the terminal in Mock OS X demo. CommandHandler is the one I’ve posted above with greet and date commands.

More Demos
There’re two more terminal demos;
* Terminal in a dialog
* Full page Terminal

Aim of PrimeFaces is to create the Ultimate Component Suite to rule them all. What PrimeFaces has so far is just the beginning.

Benchmarking Ajax JSF Libraries

Mert Caliskan posted a simple ajax performance test comparing PrimeFaces, RichFaces and Trinidad.  He used simple partial page rendering examples in demo applications which reveals PrimeFaces is 2x/3x faster than RichFaces and Trinidad. Also Alex Smirnov tested the same demo apps and got a set of different results.

Well benchmark tests usually cause debates, I’ve also done similar tests but to improve the accuracy and cause less debates I’ve created three different applications rather than using showcases. All applications are deployed on tomcat6, use server side state management and facelets for view. The box used for testing is a mac book pro 2.4 ghz with 4gb ram running snow leopard.

Let’s start with PrimeFaces.

PrimeFaces

Page: primeppr.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:p="http://primefaces.prime.com.tr/ui">
<head>
	<p:resources />
</head>
<body>
	<h:form prependId="false">
		<h:inputText value="#{testBean.text}" />
		<p:commandButton value="Submit" update="out" />
		<h:outputText id="out" value="#{testBean.text}" />
	</h:form>
</body>
</html>

Configuration: None (PrimeFaces is a lightweight library so basically there’s nothing to configure :)
primeppr

RichFaces

Page: primeppr.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:rich="http://richfaces.org/rich"
	xmlns:a4j="http://richfaces.org/a4j">
<head>
</head>
<body>
	<h:form>
		<h:inputText value="#{testBean.text}" />
		<a4j:commandButton value="Submit" reRender="out" />
		<h:outputText id="out" value="#{testBean.text}" />
	</h:form>
</body>
</html>

Configuration: As far as I know disabling forceparser improves RichFaces performance, so I set forceparser to false.

richppr

Trinidad

Page: trinidadppr.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:tr="http://myfaces.apache.org/trinidad">
<head>
</head>
<body>
	<tr:document>
		<h:form>
			<tr:inputText value="#{testBean.text}" />
			<tr:commandButton id="btn" text="Submit" partialSubmit="true"/>
			<tr:outputText id="out" value="#{testBean.text}" partialTriggers="btn"/>
		</h:form>
	</tr:document>
</body>
</html>

trinidadpprConfiguration: I’ve disabled debug setting of Trinidad in trinidad-config.xml.

Results

For 10 requests for the exact simple use case, average processing times are;

PrimeFaces: 8.4 ms

RichFaces: 16.7 ms

Trinidad: 9.7 ms (Note that Trinidad has more optimization features like view state caching which can improve the performance even further.)

I believe these results can be realized as more accurate compared to other two tests I’ve mentioned because for my tests rather than using the different showcase apps I’ve created the same application three times with each library.

I’m glad that PrimeFaces is performing well, the reason is as a result of aiming to keep things simple. PrimeFaces has no servlet filter, html parser, custom viewhandler, custom statemananger and etc. This helps PrimeFaces to keep things clean, do less computation, use less memory and be lightweight. Even acouple of PrimeFaces users were kind enough to provide testimonials which proves it. :)

Mobile Ajax Push for iPhone with PrimeFaces

PrimeFaces 1.0.0.RC aka PRIMUS will introduce the new Ajax Push aka Comet features powered by Atmosphere, after doing the initial integration I’ve created a sample chat application for a demo. It’s a simple app with login and message sending capabilities powered by http-streaming. I’ll also add support for long-polling approach soon.

After creating it, I took the integration one step further and using TouchFaces, created an iPhone app as a chat client. App will also work well with other mobile devices such as Android Phones, Palm Pre, Nokia S60 and more, any handheld device with a webkit browser is supported well.

Following is a short screencast, begins with demonstrating how easy it’s to use PrimeFaces Push and then adds more flavour with the TouchFaces client. Don’t forget to watch the video in HD. You can also play with this stuff via the online demo of PrimeFaces. Mobile chat client is also available at the TouchFaces section of PrimeFaces showcase.

PrimeFaces Talk Video and Slides

Last week, I gave my “Rapid RIA with PrimeFaces” talk at an event organized by London Java Web Users Group. The session is recorded
and available as a 90 minute podcast. Slides are also available at PrimeFaces project page.
My next stop is JSFSummit 2009 where I’ll be doing an updated version of this talk in Orlando, USA. See you there!

Last week, I gave my “Rapid RIA with PrimeFaces” talk at an event organized by London JUG. The session is recorded  and available as a 90 minute podcast. Slides are also available at PrimeFaces project page and you can watch the podcast at skills matter site.

My next stop is JSFSummit 2009 where I’ll be doing an updated version of this talk in Orlando, USA. See you there!

Posted in Developer, Java, PrimeFaces. Comments Off

PrimeFaces UI 0.9.3 is released

I am pleased to announce that new version of PrimeFaces UI Components is released. Version 0.9.3 features the TouchFaces mobile UI kit, 5 new components, improved portlet support, enhanced datatable and various improvements.

  • TouchFaces – UI Development kit for mobile devices mainly iphone
  • New component : FileUpload (Reimplemented)
  • New component : Tooltip (Reimplemented)
  • New component : PickList
  • New component : HotKey
  • New component : Virtual Keyboard
  • Easy row selection, ajax pagination, data filtering and lazy loading enhancements to DataTable
  • Significantly improved portal support for JSR168 and JSR268 portlets.
  • Pojo and Converter support for AutoComplete

See the full changelog for detailed information. Reference Documentation is also updated with 37 pages more, making it a total of 277. Additionally prime-showcase application is updated with a better looking UI.

PRIMUS

Next milestone is PrimeFaces UI 1.0.0.RC codename “PRIMUS” which will feature Ajax Push based on Bayeux protocol. Watch the teaser trailer below for more information :)

Lazy Loading JSF DataTable

I’ve actually blogged about this topic three years ago and introduced the PagedListDataModel. That solution worked at that time with some flows in design but now after three years, I’ve a much better solution to the same problem. Using PrimeFaces DataTable it’s a piece of cake to load millions of data lazily, just set the lazy to true and provide a LazyDataModel. Here’s is how it works.

<p:dataTable var="car" value="#{tableBean.lazyModel}" paginator="true" rows="10"
			dynamic="true" lazy="true">

	<p:column>
		<f:facet name="header">
			<h:outputText value="Model" />
		</f:facet>
		<h:outputText value="#{car.model}" />
	</p:column>

	<p:column>
		<f:facet name="header">
			<h:outputText value="Year" />
		</f:facet>
		<h:outputText value="#{car.year}" />
	</p:column>

	<p:column>
		<f:facet name="header">
			<h:outputText value="Manufacturer" />
		</f:facet>
		<h:outputText value="#{car.manufacturer}" />
	</p:column>

	<p:column>
		<f:facet name="header">
			<h:outputText value="Color" />
		</f:facet>
		<h:outputText value="#{car.color}" />
	</p:column>
</p:dataTable>

And the lazyModel;

public class TableBean {

	private LazyDataModel<Car> lazyModel;

	public TableBean() {
		/**
		* Test with one hundred million records.
		* In a real application use an sql Count query to get the row count.
		*/
		lazyModel = new LazyDataModel<Car>(100000000) {

			/**
			 * Dummy implementation of loading a certain segment of data.
			 * In a real applicaiton, this method should access db and do a limit based query
			 */
			@Override
			public List<Car> fetchLazyData(int first, int pageSize) {
				logger.info("Loading the lazy car data between {} and {}", first, first+pageSize);

				List<Car> lazyCars = new ArrayList<Car>();
				populateLazyRandomCars(lazyCars, pageSize, first);

				return lazyCars;
			}
		};
	}

	public LazyDataModel<Car> getLazyModel() {
		return lazyModel;
	}

	private void populateLazyRandomCars(List<Car> list, int size, int first) {
		for(int i = 0 ; i < size ; i++) {
			int offset = i + first;
			list.add(new Car("Model_" + offset, getRandomYear(), "Brand_" + offset, "Color_" + offset));
		}
	}
}

That’s just it, whenever a paging event occurs with ajax, your fetchLazyData implementation will be called with the offset and pageSize. In a real application, you need to use your specific data access methods to load a chunk of data between a certain interval. For example in JPA api setMaxResults(pageSize) and setFirstResult(first) would do the trick. Also you need to define how many virtual records are there to be displayed so that PrimeFaces DataTable can create it’s paginator using that value, as an example a count/projection query could be used.

So to sum up, with PrimeFaces DataTable lazy loading capabilities even if you have billions of records, you can enable lazy loading very easily since number of all records are not relevant, only the records on the current datatable page is loaded.

There’s an online demo that demonstrates how to display one hundred million(100000000) records with this feature with paging happening less than a second.

PrimeFaces UI 0.9.3 Trailer

PrimeFaces UI 0.9.3 is coming soon with many new features and improvements, here’s the video of the trailer :)

“Rapid RIA with PrimeFaces” talk

On 6th of October, I’ll be doing my “Rapid RIA with PrimeFaces” talk at Skills Matter, London. This is a free event organized by London Java Web Users Group. See the announcement for more information and registration. Hopefully after the event, we’ll head over to the nearby pub for drinks and further discussion.

Posted in Developer, Java, PrimeFaces. Comments Off

Sample iPhone Apps with TouchFaces

For demonstration purposes I’ve created a couple of sample iPhone apps using TouchFaces. Here’s a short screencast explaining how these apps work and how easy it is to implement them with PrimeFaces.

These apps are deployed online so you can test them with your iphone or a webkit based mobile browser. Demo page also contains pointers to the source codes.

“Rapid RIA with PrimeFaces” slides

First of all thanks to EMC Conchango for inviting me to their communit day sessions, my talk was titled as “Rapid RIA Development with PrimeFaces”. You can find the slides of my presentation at PrimeFaces homepage documentation section. In october I’ll be doing an updated version of this talk at London Java Web Users Group.

Posted in Developer, Java, PrimeFaces. Comments Off

IPhone App Development with JSF

TouchFaces is a UI development kit to create IPhone web applications with JSF. TouchFaces is a member of PrimeFaces family and will be shipping with the UI module. Basically it allows developing applications using JSF with the native IPhone look and feel, plus it’s powered by PrimeFaces UI infrastructure and Ajax is built-in.

I’ll also publish detailed articles soon but recently I’ve created a screencast as a getting started tutorial. Enjoy!

Update: See sample iphone apps and mobile push for further information.