Programatically creating a WODisplayGroup

I like WODisplayGroups. OK, call me crazy – or lazy – but I like them alot. However, I do find that I often need more control over them than the drag and drop creation gives me. So here is how I like to set up WODisplayGroups programatcially:

Just to prevent any potential confusion: This example demonstrates creating a WODisplayGroup from scratch, and will not work if you’ve created one by dragging an Entity from EOModeler into WebObjects Builder. – Thanks Alex!

Using this pattern setup the _displayGroup object

protected WODisplayGroup _displayGroup;
 
public WODisplayGroup displayGroup() {
	if (_displayGroup == null) {
		prepDisplayGroup();
		find();
	}
	return _displayGroup;
}
public void setDisplayGroup(WODisplayGroup dg) {
	_displayGroup = dg;
}

Add the prepDisplayGroup() method:

public void prepDisplayGroup() {
	_displayGroup = new WODisplayGroup();
	_displayGroup.setNumberOfObjectsPerBatch(10); 
	EOSortOrdering asc = EOSortOrdering.sortOrderingWithKey(
			"keyToSortOn", 
			EOSortOrdering.CompareAscending);
	NSArray ordering = new NSArray(new Object[] {asc});
	_displayGroup.setSortOrderings(ordering);
}

The WODisplayGroup API is here

Finally add the find() method:

public void find() {
	NSArray foundObjects = //fetch your objects here
	displayGroup().setObjectArray(foundObjects);
}

In my find() method I usually take advantage of the objectsFor... methods that can be generated by EOGenerator. These wrap your EOModel’s fetchSpecs in static methods in your EO’s, very cool. Take a look at the EOGenerator EOGJavaSource.eotemplate for more details. Update: I’ve blogged more details about my EOGenerator templates here

I often base my search pages on a common super class that includes a displayGroup along with variables for setting objects per batch and a search string amongst other things.

Lazy WOComponent ivar initialization

How do you setup instance variables if they need to be initialized after their WOComponent is fully formed?

Overiding the awake() method happens too early, so you’re usually left overriding later in the request-response loop *. Here is a nice simple alternative pattern that I use all the time.

  1. Create your instance variables (I like to make them protected at least)
    protected NSArray _myThings;
  2. Give your ivars public accessor methods
    public NSArray myThings() {
    	return _myThings;
    }
     
    public void setMyThings(NSArray array) {
    	_myThings = array;
    }
  3. Modify the getter method so it follows this pattern:
    public NSArray myThings() {
    	if (_myThings == null) {
    		//initialize _myThings here
    	}
    	return _myThings;
    }

This pattern works really well for setting up things like display groups or arrays of fetched objects. If you bind to the accessor method in your WOComponent, the first time the method is hit, the values will be initialized. Very clean and easily understood. I like it a lot 🙂

* You do know the stages of the request-response loop don’t you? If you don’t buy Chuck’s book. Do it now. I’ll wait…