List Model

From Documentation

Listbox and Grid allow developer to separate the view and the model by implementing ListModel. Once the model is assigned (with Listbox.setModel(ListModel)), the display of the listbox is controlled by the model, and an optional renderer. The model is used to provide data, while the renderer is used to provide the custom look. By default, the data is shown as a single-column grid/listbox. If it is not what you want, please refer to the View section for writing a custom renderer.

Model-driven Display

DrListModelRenderer.png

As shown, listbox retrieves items from the specified model[1], and then invokes the renderer, if specified, to compose the listitem for the item.

The retrieval of items is done by invoking ListModel.getSize() and ListModel.getElementAt(int).

The listbox will register itself as a data listener to the list model by invoking ListModel.addListDataListener(ListDataListener) Thus, if the list model is not mutable, the implementation has to notify all registered data listener. It is generally suggested to extend from AbstractListModel which provides a set of utilities for handling data listeners. Then, you need to only implement ListModel.getSize() and ListModel.getElementAt(int).


  1. The listbox is smart enough to read the items that are visible at the client, such the items for the active page. It is called Live Data or Render on Demand'.'

Small Amount of Data

If your data can be represented as a list, map, set or array (java.util.List, java.util.Map, etc.), you could use one of the default implementations, such as ListModelList, ListModelMap, ListModelSet and ListModelArray. For example,

void setModel(List data) {
    listbox.setModel(new ListModelList(data));
}

If the amount of your data is small, you could load them all into a list, map, set or array. Then, you could use one of the default implementations as described above.

Alternatively, you could load all data when ListModel.getSize() is called. For example,

public class FooModel extends AbstractListModel {
    private List _data;
    public int getSize() {
        //load all data into _data
        return _data.size();
    }
    public Object getElementAt(int index) {
        return _data.get(index);
    }
}

Hug Amount of Data

If the data amount is huge, it is not a good idea to load them all at once. Rather, you shall load them only when required. However, it is generally not a good idea to load single item when ListModel.getElementAt(int) is called, since the overhead of loading from the database is significant.

Thus, it is suggested to use SQL LIMIT or similar feature to load only a portion of the data. For example, if the total number of visible items is about 30, you could load 30 or more (such as 60, depending on performance or memory is more important) if an item is not found, and discard the previous data, if any. If the next invocation of ListModel.getElementAt(int) is in the subset, we could return it immediately. Here is the pseudo code:

public class FooModel extends AbstractListModel {
    public List _subset;
    public int _startAt;

    public Object getElementAt(int index) {
        if (index >= _startAt && _subset != null && index - _startAt < _subset.size())
            return _subset.get(index - _startAt);
        //drop _subset, and load a portion of data, say, 60, to _subset
        ...

Version History

Last Update : 2010/12/29


Version Date Content
     



Last Update : 2010/12/29

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.