Layout Managers
- Overview
- Goal: Assign space, size, and a position to each set of objects in a
container
- Position: the object's x/y coordinates
- Size: the object's width/height
- Space: the size of the region in which an object is placed: The
size of the region could be bigger than the object's size
- Issues
- How to assign a position to an object
- How to assign a size to an object
- How to assign space to an object
- How to align an object when the space it is assigned
exceeds its size
- How to assign a new position/space/size to an object
when it's window or container is re-sized
- General Strategy for Layout Algorithms
- Bottom-up pass: Ask each component for its preferredSize and aggregate the
sizes
- Top-down pass: Assign each component its position, space, and
size
- Layout in Java
- Overview of Java Layout
- Java has the notion of containers and components.
Containers are objects that can contain other objects and components
are either containers or primitive objects.
- Each container has a layout algorithm associated with it
- Java supports different layout algorithms. However,
since it is not possible to pass function pointers in Java, we must
instead place each layout algorithm in a class. The class is also able
to store state information that helps with the layout of the
container. An instance of the appropriate layout manager is
assigned to a container using the container's setLayout method.
- Each component specifies three quantities to assist the
layout manager
- preferredSize: it's preferred width/height
- minimumSize: the minimum size it wants to be
displayed at
- maximumSize: the maximum size it wants to be
displayed at
- All layout managers take components' preferredSize
into account when computing the initial size of a window.
However, when a window is re-sized, then these three
quantities may be ignored by the layout manager.
- Java's layout managers
- Border Layout: For top-level of an application and putting pallettes around a canvas object
- Divides a container into 5 regions and when you
add an object to a container, you specify which
region it should be placed in.
- center
- page_start (north)
- page_end (south)
- line_start (west)
- line_end (east
- Can specify horizontal/vertical gaps between
regions
- Respects preferredWidth for East/West regions and preferredHeight for
North/South regions
- Center region gets all of the extra space
- Flow Layout: Horizontally lays out objects at their natural size.
- When the container is re-sized
- If the container is not wide enough to
accommodate all the objects, then the flow
layout uses multiple rows
- If the container is wider than the
combined width of the objects, then the
row of objects is left-aligned, centered, or
right-aligned depending on the alignment
that is specified when the instance of the
FlowLayout algorithm is created.
- Parameters to the algorithm
- hgap: horizontal space between
objects
- vgap: vertical space between objects
- alignment: how to align the rows
if the rows' width is less than the width
of the container. Options are
left/centered/right.
- Grid Layout: Lays out objects in a table with each
object having the same width/height
- Typically used for tool pallettes
- Sets width to the max width component and the
height to the max height component: Hence only
the preferred width of the max width component and
the preferred height of the max height component are
respected
- Parameters
- hgap: horizontal space between objects
- vgap: vertical space between objects
- Can specify number of rows and/or columns:
can set either to 0 but not both. For example,
if you set rows to 0 and columns to 3, then
there can be an infinite number of rows and
each row will have up to three objects.
- When you resize the container, the space is
divided evenly among the objects
- The order in which you add objects to the
container determines the order in which they
are laid out
- If you specify the number of columns, then
objects are laid out left-to-right, top-to-bottom
- If you set the number of columns to 0, then
objects are laid out top-to-bottom, left-to-right.
- Box Layout: Lays out objects in either vertical/horizontal stacks (rows) and it provides a variety of layout controls
- Parameters: Can choose axis for layout
- horizontal: BoxLayout.LINE_AXIS
- vertical: BoxLayout.PAGE_AXIS
- When resizing the container
- For horizontal layout, it tries to respect preferredHeight.
- as you increase the width, BoxLayout increases the width of
each object up to its maximum preferred width
- as you decrease the width, BoxLayout decreases the width of
each object down to its minimum preferred width
- For vertical layout, it tries to respect preferredWidth
- as you increase the height, BoxLayout increases the height of
each object up to its maximum preferred height
- as you decrease the height, BoxLayout decrease the height of
each object down to its minimum preferred height
- Fillers: fillers are invisible objects that allow you
to control the spacing between objects. Filler objects are
added to containers like other visible objects
- Rigid Area: invisible object that gives you fixed space between
two objects (use rigid areas rather than horizontal/vertical struts
for fixed space because horizontal/vertical struts have infinite
height/width that can mess up layout calculations)
Examples
- Box.createRigidArea(new Dimension(10, 0)): creates a horizontal box 10 pixels wide and
0 pixels high--would be added to a
horizontal layout to put 10 pixels between
two objects
- Box.createRigidArea(new Dimension(0, 10)): creates a vertical box 10 pixels high and 0 pixels wide--would be added to
a vertical layout to put 10 pixels between
two objects
- Glue objects: invisible objects that expand/shrink as space is allocated to or removed from a container
- each glue object is made the same size as all other glue objects
- common uses
- keep objects "squashed" against sides of the container
- center objects in the middle of the container
- evenly space objects in the container
- types of glue
- horizontal glue: has 0 minimum width and infinite maximum width
(essentially has 0 height)
- vertical glue: has 0 minimum height and infinite maximum height
(essentially has 0 width)
- Creating a BoxLayout manager
- JPanel foo = new JPanel(new BoxLayout(BoxLayout.LINE_AXIS));
- Box foo = Box.createHorizontalBox(); -- Box is a container object that uses the box layout manager
- Gridbag Layout: Good for dialog boxes and general layouts.
- Roughly lays out objects in a grid but with different sized rows and
columns.
- Objects can span multiple rows/columns
- Can control how objects are aligned/anchored in their assigned space
- Too complicated to be discussed in this course
- Important methods associated with layout managers
- JFrame methods
- pack(): invokes layout manager on the JFrame's content pane.
- The layout manager will size the window so that it's just big enough
to accommodate the objects at their preferred width and height
- You should always call the pack method right before you
make the JFrame visible
- If you want a window to resize itself after adding or
removing a component from a JPanel, you will need to call
the pack method
- getContentPane(): gets container object for the JFrame--you
should downcast this object to a JPanel
- JPanel methods
- setLayout(instance of layout manager): sets layout manager
- add(component, parameters): adds components to a container
and the parameters provide layout hints. For example, with
a BorderLayout manager you would provide a parameter specifying
the region where the object should be placed
- revalidate(): indicates that the layout manager for this
panel must be called to re-layout the panel's components. You
should call this method any time you add or remove components
from a panel.
- repaint(): indicates that the panel should be repainted.
You should call this method after calling revalidate() since
you want the panel redrawn after it's been laid out
- Debugging: Put garish borders around objects to see what their size is