Up until now we've only considered examples consisting of a lonely component inside a window. Most programs aren't that simple, and we will now look at some of the ways at how we can layout multiple components.
This physical composition of components in a window can be done in countless number of ways, but to start out modestly, let's consider how to align a set of components horisontally (the mkDC and realiseDH functions are explained in the next section):
hbox :: [DisplayHandle] -> DisplayHandle main = mkDC ["*name: Box"] >>= \ env -> myButton "On" "Off" env >>= \ (_,dh1) -> myButton "Start" "Stop" env >>= \ (_,dh2) -> realiseDH env (hbox [dh1,dh2]) >> return ()

Two instances of the button abstraction created in the previous section are put next to each other horisontally using the layout combinator hbox. It takes a list of DisplayHandles and returns a new one representing the combined box. To recapitulate, a DisplayHandle is a handle the `user interface part' of a component, being used to communicate system commands and requests to the component it represents. So, for hbox, it takes a list of these user interface handles, ask the components they represent for their size and compute the horisontal layout.
Note that the DisplayHandle returned by hbox is just like any other DisplayHandle, there is no way of telling whether it has been composed out of other DisplayHandles or is a `primtive' DisplayHandle. To see this, let's create even more buttons:
pair :: Component [DisplayHandle]
pair env =
myButton "On" "Off" env >>= \ (_,dh1) ->
myButton "Start" "Stop" env >>= \ (_,dh2) ->
return [dh1,dh2]
main =
mkDC ["*name: Boxes"] >>= \ env ->
pair env >>= \ ls1 ->
myButton "On" "Off" env >>= \ (_,dh1) ->
pair env >>= \ ls2 ->
realiseDH env
(hbox [vbox ls1,
dh1,
vbox ls2]) >>
return ()

This time the hbox lays out DisplayHandles that come from myButton and results from applying the vbox layout combinator, hbox' vertical friend.
Complete layout hierarchies can be built using the hbox and vbox layout combinators, although sometimes we want to have some space inbetween the components of a box
space :: Int -> DisplayHandle
The space is a little user interface component whose only mission in life is to occupy some window real estate:
main = mkDC ["*name: Box"] >>= \ env -> myButton "On" "Off" env >>= \ (_,dh1) -> myButton "Start" "Stop" env >>= \ (_,dh2) -> realiseDH env (hbox [dh1, space 20, dh2]) >> return ()

Each DisplayHandle has a bounding box associated with it. If this bounding box of a component is resized by the user changing the size of a window, say, we want the component to adapt to this new size and redisplay itself. The DisplayHandles returned by hbox and vbox will upon being resized, distribute the change in size between the list of DisplayHandles they are tiling. In many cases, distributing the change in size evenly between these components is fine, but sometimes we want to have better control over the resize behaviour. For instance, suppose we want the above space DisplayHandle to soak up all the change in size when doubling the size of the enclosing hbox.
To express this, a DisplayHandle has a set of geometric requirements associated with it. These include inexampleion on what the component's natural and minimum size is and how willing it is to be stretched and squashed from its natural size. So to compute their layout, the box combinators uses not only the natural sizes of their components, but also the hints about how willing they are to deviate from that natural size. So to make the space extra stretchy:
main =
mkDC ["*name: Box"] >>= \ env ->
myButton "On" "Off" env >>= \ (_,dh1) ->
myButton "Start" "Stop" env >>= \ (_,dh2) ->
realiseDH env (hbox [dh1,
withStretch (2,1) (space 20),
dh2]) >>
return ()

This style of layout is very similar to the TeX' boxes-and-glue model for text exampleting, text boxes and inter-box glue being substituted with user interface component DisplayHandles.
Several other abstractions exist for presenting components together, but they all have the form of
layoutCombinator :: [DisplayHandle] -> DisplayHandle
i.e., taking a list of components to manage the layout of, and returning the DisplayHandle representing the layout combinator.