Skip to main content

Data Display

Coming from Selection & Text, let's move to controls built for showing a whole collection at once, rather than a single value or piece of text.

info

Every control here is built on a model (ListModel, TreeModel, and so on) plus an ItemVisualizer that renders each item. That split — data on one side, presentation on the other — is what lets the same control show wildly different kinds of data without you writing a new one each time.

The Dynamic* vs Mutable* types map to readonly (though not constant) to fully editable.

Which one do you actually want?

Your data is...Reach for
A flat collection, one line eachList
A flat collection, needing multiple columnsTable (editable: MutableTable)
Specifically key/value pairsKeyValueTable
Naturally nestedTree
Nested, and needing multiple columnsTreeTable
Best stepped through one (or a few) at a timeCarousel

List​

The visual analog to the list data structure: a read-only, ordered collection of items with random access, each rendered through an ItemVisualizer. Reach for this as your default whenever "show a collection" is the whole job.

It's memory-efficient by design — only the items actually visible in the viewport get rendered, with Views recycled as the user scrolls rather than rebuilt from scratch. That cache defaults to 0 items beyond what's visible, and you can tune it with the scrollCache property when you create the List.

Need the underlying data to change after the List is built? Plain List assumes a fixed model. DynamicList is the same read-only control but with a model that can change out from under it — handy for something like items streaming in asynchronously. MutableList goes a step further and allows the user to edit it directly.

Icons made by Freepik
Icons made by Freepik
Icons made by Freepik
tip

Lists delegate rendering ListBehavior or use a Theme since Lists delegates rendering.

Table​

List's multi-column sibling — rows of a single, strongly-typed item type <T>, each broken into columns. Every column gets its own CellVisualizer, which is handed just the value for that column (i.e. String for a name column, a Boolean for an "attending" checkbox column) and turns it into a View — columns can even derive an arbitrary value from the row rather than reading a property directly, the way a row-number column would. Reach for Table once a single line of text per item isn't enough.

Same pattern as List: plain Table assumes a fixed model, DynamicTable supports a model that changes after creation, and MutableTable (below) allows editing on top of that.

MutableTable​

Table, with editing enabled — cells can be changed in place, and the table can perform CRUD operations or reorder itself (sorting by a column, say) by modifying its own model directly.

KeyValueTable​

A Table specialized for exactly one job: showing key/value pairs, one per row. Reach for this over a general Table whenever what you're actually displaying is closer to a property list than arbitrary tabular data.

Tree​

The visual analog to a tree data structure — nested, expandable/collapsible items, each rendered through an ItemVisualizer. You need two things to build one: a TreeModel, and an ItemVisualizer.

tip

DynamicTree is readonly (though its models may change), while MutableTree is read/write.

TreeTable​

Tree and Table combined — hierarchical, expandable rows, each broken into columns. Reach for this when your data is naturally nested and needs more than one column per item, which is exactly the combination neither Tree nor Table covers alone. You need 2 things to create a Tree: a TreeModel, and ItemVisualizer.

Another visual analog to a list, this time optimized for stepping through items one (or a few) at a time rather than showing them all at once — an image gallery is the classic use case. It's read-only; see DynamicCarousel if you need the items themselves to change at runtime. Like List, it's built for scale — only the items its Presenter actually displays get rendered, with Views recycled as it scrolls, so a Carousel can hold enormous datasets without the performance cost.

Three things go into building one: a ListModel, an ItemVisualizer, and a CarouselBehavior. That Behavior is where the real flexibility lives — it supplies a Presenter (which items are shown, and their bounds, transform, opacity, zOrder) and a Transitioner (how the Carousel moves between items). Mix and match either independently to get a wildly different feel from the same data:

tip

A Presenter isn't limited to the items in your model — ReflectionPresenter's "floor" is a Supplemental View it adds on top, for exactly this kind of extra decoration a Presenter wants to contribute beyond what the model provides.

A Carousel is also a genuinely nice fit for a calendar: this demo uses one with LinearPresenter over a list of month-start dates, showing one or two months side by side depending on how much width is available.

Recap​

  • List is the default for showing a collection; reach for Table once one line of text per item stops being enough, and KeyValueTable specifically for property-style key/value data.
  • Tree handles nested data; TreeTable is what you want when that nested data also needs multiple columns.
  • Carousel is built for stepping through items rather than showing them all — think galleries, not lists.
  • Every control here is model + ItemVisualizer — swap either independently to change what's shown or how it looks.

Next: on to Panels & Layout for arranging other Views.