Lists

List components in Pivot include ListView and ListButton. ListView is a (often scrollable) list of items of which one or more may be selected. ListButton is a popup list of items of which only one may be selected at a time. It is often used in place of a group of radio buttons, particularly when space is limited.

ListButton is discussed in the next section. The following example demonstrates the ListView component. Multiple items may be selected at a time, and list selections are reflected in the label to the right.

The BXML source for the example follows. Note that the list view is itself contained within a ScrollPane. List views do not support scrolling internally. This allows a UI designer to place a list view within an application and have the list view simply grow to accommodate its contents, rather than requiring the designer to specify a fixed height for the list in advance. However, if the designer knows that the list will be long and that it is likely to scroll, it can be placed in a scroll pane. ScrollPane is discussed in more detail in the Navigation Containers section.

Also note that the list's contents are specified in the BXML document itself, as a JSON array of strings in the listData attribute. Any type of object can actually be used as a list item, provided that the list view has been given a renderer that is capable of painting it. However, they are most often specified as strings (as in this example) or as instances of org.apache.pivot.wtk.content.ListItem, both of which the default renderer is capable of presenting.

            
            <lists:ListViews title="List Views" maximized="true"
                xmlns:bxml="http://pivot.apache.org/bxml"
                xmlns:lists="org.apache.pivot.tutorials.lists"
                xmlns="org.apache.pivot.wtk">
                <Border>
                    <BoxPane styles="{padding:4, spacing:4}">
                        <Border styles="{color:10}">
                            <ScrollPane preferredWidth="80" preferredHeight="110"
                                horizontalScrollBarPolicy="fill"
                                verticalScrollBarPolicy="fill_to_capacity">
                                <ListView bxml:id="listView" selectMode="multi"
                                    listData="['One', 'Two', 'Three', 'Four', 'Five',
                                        'Six', 'Seven', 'Eight', 'Nine', 'Ten']"/>
                            </ScrollPane>
                        </Border>
                        <BoxPane orientation="vertical" preferredWidth="120" styles="{fill:true}">
                            <Label text="You selected:"/>
                            <Label bxml:id="selectionLabel" styles="{wrapText:true}"/>
                        </BoxPane>
                    </BoxPane>
                </Border>
            </lists:ListViews>
            
        

The Java code for the example also uses the list data to populate the label component as the list selection changes. A ListView's selection is represented by a sorted list of org.apache.pivot.wtk.Span objects that contain the currently selected ranges; the application retrieves the list of currently selected ranges and then constructs the label's text by appending each selected item to the string:

            
            package org.apache.pivot.tutorials.lists;

            import java.net.URL;

            import org.apache.pivot.beans.Bindable;
            import org.apache.pivot.collections.Map;
            import org.apache.pivot.collections.Sequence;
            import org.apache.pivot.util.Resources;
            import org.apache.pivot.wtk.Label;
            import org.apache.pivot.wtk.ListView;
            import org.apache.pivot.wtk.ListViewSelectionListener;
            import org.apache.pivot.wtk.Span;
            import org.apache.pivot.wtk.Window;
            import org.apache.pivot.wtk.content.ListItem;

            public class ListViews extends Window implements Bindable {
                private Label selectionLabel = null;
                private ListView listView = null;

                @Override
                public void initialize(Map<String, Object> namespace, URL location, Resources resources) {
                    selectionLabel = (Label)namespace.get("selectionLabel");
                    listView = (ListView)namespace.get("listView");

                    listView.getListViewSelectionListeners().add(new ListViewSelectionListener() {
                        @Override
                        public void selectedRangeAdded(ListView listView, int rangeStart, int rangeEnd) {
                            updateSelection(listView);
                        }

                        @Override
                        public void selectedRangeRemoved(ListView listView, int rangeStart, int rangeEnd) {
                            updateSelection(listView);
                        }

                        @Override
                        public void selectedRangesChanged(ListView listView, Sequence<Span> previousSelectedRanges) {
                            if (previousSelectedRanges != null
                                && previousSelectedRanges != listView.getSelectedRanges()) {
                                updateSelection(listView);
                            }
                        }

                        @Override
                        public void selectedItemChanged(ListView listView, Object previousSelectedItem) {
                            // No-op
                        }

                        private void updateSelection(ListView listView) {
                            String selectionText = "";

                            Sequence<Span> selectedRanges = listView.getSelectedRanges();
                            for (int i = 0, n = selectedRanges.getLength(); i < n; i++) {
                                Span selectedRange = selectedRanges.get(i);

                                for (int j = selectedRange.start;
                                    j <= selectedRange.end;
                                    j++) {
                                    if (selectionText.length() > 0) {
                                        selectionText += ", ";
                                    }

                                    Object item = listView.getListData().get(j);
                                    String text;
                                    if (item instanceof ListItem) {  // item is a listItem (for example because it has an image)
                                        text = ((ListItem) item).getText();
                                    } else {  // item is a standard item for listData
                                        text = item.toString();
                                    }
                                    selectionText += text;
                                }
                            }

                            selectionLabel.setText(selectionText);
                        }
                    });
                }
            }
            
        


Sample ListView containing ListItems, and a renderer to display images for any item.

The BXML source for the example follows.

In this case list contents are set using the content namespace, they are ListItem instances (not only plain Strings as the previous sample), and there is a ListViewItemRenderer set. Note that references to images (icon) here are set in a relative path, to reuse images already existing just for convenience.

            
            <lists:ListViews title="List Views with Images" maximized="true"
                xmlns:bxml="http://pivot.apache.org/bxml"
                xmlns:content="org.apache.pivot.wtk.content"
                xmlns:lists="org.apache.pivot.tutorials.lists"
                xmlns="org.apache.pivot.wtk">
                <Border>
                    <BoxPane styles="{padding:4, spacing:4}">
                        <Border styles="{color:10}">
                            <ScrollPane preferredWidth="80" preferredHeight="110"
                                horizontalScrollBarPolicy="fill"
                                verticalScrollBarPolicy="fill_to_capacity">
                                <ListView bxml:id="listView" selectMode="multi"
                                >
                                    <itemRenderer>
                                        <content:ListViewItemRenderer iconWidth="16" iconHeight="16"
                                            showIcon="true"
                                        />
                                    </itemRenderer>

                                    <content:ListItem icon="@../anchor.png" text="Anchor"/>
                                    <content:ListItem icon="@../bell.png" text="Bell"/>
                                    <content:ListItem icon="@../clock.png" text="Clock"/>
                                    <content:ListItem icon="@../cup.png" text="Cup"/>
                                    <content:ListItem icon="@../house.png" text="House"/>
                                    <content:ListItem icon="@../star.png" text="Star"/>
                                </ListView>
                            </ScrollPane>
                        </Border>
                        <BoxPane orientation="vertical" preferredWidth="120" styles="{fill:true}">
                            <Label text="You selected:"/>
                            <Label bxml:id="selectionLabel" styles="{wrapText:true}"/>
                        </BoxPane>
                    </BoxPane>
                </Border>
            </lists:ListViews>
            
        

The Java code for the example is the same seen in the previous sample.



In case your ListView contains a bean instance, for example a Contact for any element, the default renderer uses (as last option) the toString method on list elements, so override it to return whatever you want to display in the ListView, or implement your own custom renderer.

Next: List Buttons