Barracuda Component Model Tutorial - HelloWorld 2a

<<|Preface|HelloWorld 1|1a|1b|2|2a|2b|3|4|>>

barracuda.gif (11456 bytes) Thanks but I'd prefer organic please - Ok, so embedding directives in markup is not for everyone! This example shows how we can accomplish the same thing using a BList component to drive our grocery list.

Taking a look at the Template

Unlike the previous examples which used BTemplate, here we want to start by taking a look at the template source. If you are familiar with XMLC, this should very much like the type of thing you are used to seeing in a template:

<html>
    <head><title id=
"Title1">[Title]</title></head>
    <body style="font-family: Georgia, Arial, Times New Roman">
        <h2 id=
"Title2">[Title]</h2>
        <p id=
"Descr">[Descr]</p>
        <p>Here's our simple shopping list:</p>
        <ul id=
"ShoppingList">
            <li id="Item">3 cans Corn</li>
            <li>4 bags Peas</li>
            <li>1 bunch Bannanas</li>
            <li>...</li>
        </ul>
        <p id=
"Footer" align="center">[Footer goes here]</p>
    </body>
</html>

The only thing "extra" in the HTML are the standard XMLC style ID tags. Ok, you ask, so what's the source code look like?


Taking a look at the Source

Alright, now let's dig deeper by looking at the source. This time we see some significant differences from previous examples.

The first thing we should point out is that we are using standard XMLC generated methods to populate "flat" data points; we could use BText components here, but it actually requires a few more lines of code so we won't. Instead, we see this:

page.setTextTitle1("Hello World 2a example");
page.setTextTitle2("Hello World 2a example");
page.setTextDescr("This example illustrates...");

Ok, so what about the list? How is that handled? Well, here is the code to set up the BList component.

String[] items = new String[] {"Cabbage", "Carrots", "Pickles",
                               "Sugar", "Wheaties", "Flour", "Potatoes"};
String[] qtys = new String[] {"3 heads", "1 bag", "1 jar",
                              "5 lbs", "3 bxs", "50 lbs", "25 lbs"};
ListModel listModel = new GroceriesModel(items, qtys);
View listView = new DefaultView(page.getElementShoppingList());
BList wcList = new BList(listModel);
wcList.setView(listView);
root.add(wcList);

Let's briefly discuss what is going on here. First, we are setting up the arrays that will back the model. This is very similar to the previous examples. Next, we create a ListModel, followed by a View that is bound to the node with the "ShoppingList" id. Once we have our model and view prepared, all that is left is to instantiate the list and then add it to the root component.

Ok, so far so good. Now what's the model look like? In the case of List components, the model is very simple and Swinglike. It consists of two key methods:

  1. public int getSize() - return the number of items in the list

  2. public Object getItemAt(int index) - get a particular item at a given position within the list.

In our case here, the actual model implementation looks something like this:

class GroceriesModel extends AbstractListModel {

    String[] items = null;
    String[] qtys = null;

    //constructor
    public GroceriesModel(String[] iitems, String[] iqtys) {
        items = iitems;
        qtys = iqtys;
    }

    //provide items by pos
    public Object getItemAt(int index) {
        return qtys[index]+" "+items[index];
    }

    //get the size of the list
    public int getSize() {
        return items.length;
    }
}

Wow, pretty easy, right? Well, yes an no. In this case, we're simply concatenating our quantity and item description strings together, and returning the resulting string as a list item. As soon as we want to get a little more sophisticated--say we'd like to use rows out of the XMLC template as "list item templates"--then it becomes more complex because we have to look up the specific row template, clone it, and then bind the data to the appropriate portions of that. The components support this type of thing, but it quickly becomes more work for the developer (in contrast, this is an area where the BTemplate really shines).

But hey, the primary purpose of this example is to demonstrate that you don't have to use the BTemplate if you don't want to. There are always other options available.


A Brief Word About the Footer

We would be remiss if we didn't say at least a little something about the footer in this example. Because we don't want to use the BTemplate component, we need to find some alternative approach to inserting the footer into the document. Here's how we do it.

First, we create a list component and bind it to the "Footer" node. The code is straightforward and looks something like this:

DefaultListModel flistModel = new DefaultListModel();
View flistView = new DefaultView(page.getElementFooter());
BList fwcList = new BList(flistModel);
fwcList.setView(flistView);
root.add(fwcList);

Now you may find yourself saying, "What? A list component? But the footer isn't a List?" Actually, the footer may not be a list, but the Node returned has children, and those can be viewed as a list quite nicely. Look at how we continue:

Node fn = HelloWorld2Footer.getNode(page.getDocument());
NodeList nl = fn.getChildNodes();
for (int i=0,max=nl.getLength(); i<max; i++) {
    flistModel.add(nl.item(i));
}

Here we grab the footer node and then iterate through it's children (Nodes), adding them into the list model. Now when the list component queries its model, it will find a whole list of Node components, which it can add quite easily beneath the node to which it is bound. Nifty.

Click here to return to the Barracuda Component Model Tutorial page.

For all the latest information on Barracuda, please refer to http://barracuda.enhydra.org
Questions, comments, feedback? Let us know...
Copyright 1997-2002 Lutris Technologies, Inc. All rights reserved.