Java - Containers
Java - Containers
Layout managers
Definition of a Container
Containers are on screen windows that contain controls or other subcontainers. A container, and all of the objects within that container, can be
moved, hidden, shown, etc. in a single operation (e.g. whenever the
setVisible() method is called on a JFrame object, all the components
within that JFrame are also painted). Top-level containers are defined as
those which can be displayed directly on the desktop. Non top-level
containers must be displayed within the context of another top-level container.
Container hierarchy
The Java AWT and Swing container hierarchies follow. Note, with one exception
(WindowPopup) all Java containers are prefixed with a J, e.g. JWindow, JFrame,
etc.
java.awt.Component
java.awt.Container
JComponent
Window
Panel
Frame
Dialog
JFrame
JDialog
Applet
JWindow
JApplet
JPanel
WindowPopup
javax.Swing containers
Containers are mostly derived from one of two superclasses, either java.awt.Window or
java.awt.Panel. JPanel is an exception to this, and is derived from JComponent. Broadly
speaking, panels are intended for use within applets, whereas windows are intended for use
within applications.
PAGE
74
LECTURE 6
Evidently, containers inherit all of the methods declared within the component class, entailing
that they can have their size queried and set, be hidden and shown, etc. However, it is best to
regard java.awt.Container as being the focal superclass of all containers. It is considered next.
Adding/removing components
Components may be added to a container through the public Component add( Component
comp ) method. Likewise a component can be removed via the use of the public void
remove( Component comp ) method.
A few other add/remove methods are available, permitting a component to be added at a
particular index and/or using a particular set of layout constraints (e.g. someContainer.add(
someComponent, BorderLayout.NORTH )). Additionally, the
public void removeAll() method can be used to remove all
components from a container.
A number of methods are provided that enable the components
contained within the container to be retrieved. For example the public
Component[] getComponents() method returns an array of all the
components contained within the container, whereas the public Component getComponent(
int n ) returns the nth component and the public Component getComponentAt( int x, int y )
returns the component that touches point (x,y).
Note, public void addContainerListener( ContainerListener listener)
and public void removeContainerListener( ContainerListener listener)
methods are available. However, a container listener should only be used for
notification purposes. Finally, the public int getComponentCount() returns
the number of components within the container.
Layout managers
Each container possesses a layout manager that determines how components are sized and
positioned within the container (the various layout managers are explored later).
The particular layout manager that is in effect can be obtained via the public LayoutManager
getLayout() method and likewise set using the public void setLayout( LayoutManager mgr
) method. The layout manager can be forced to layout all the components by
calling the public void doLayout() method. Note, it is recommended that the
programmer does not call doLayout() directly, instead they should call public
void validate() which, when invoked, results in the doLayout() method being
called if an update is necessary.
The related method public void invalidate() should be called whenever the
programmer needs to inform the AWT that the container should be reformed
(i.e. all components are repositioned and redrawn).
PAGE
75
LECTURE 6
Swing Containers
In what follows the different types of Swing container will be explored. Before this, it is
necessary to highlight the differences between an AWT container and a Swing container.
Principally, a Swing container is intended to store lightweight components, whereas an AWT
container is intended to store heavyweight components.
In order to ensure components can be displayed in a flexible manner, Swing containers define
several different layers (in contrast AWT containers contain a single layer). An overview
follows:
JFrame
JWindow
JApplet
JDialog
JPanel
JInternalFrame
JRootPane
JLayeredPane
JMenuBar
JGlassPane
JContentPane
JFrame, JWindow, JApplet and JDialog are top-level containers (i.e. can appear on their own
on the screen). This is not true of JPanel and JInternalFrame, which must appear within the
confines of a top-level container.
PAGE
76
LECTURE 6
Starting from the top down, the various layers within a Swing container are as follows:
JGlassPane. This pane overlays all the other panes and is intended to permit the
programmer to draw over the entire container without getting distracted by the
components within the container.
JContentPane. Components are added to this pane, e.g.
mySwingContainer.getContentPane().add( someComponent), etc. The
layout manager also operates within the confines of the content pane, determining
how components should be sized and positioned within this pane (by default a
border layout is assumed).
JMenuBar. This pane is used for displaying any menus associated with the Swing
container.
JLayeredPane. This pane resides under the content and menubar panes. Many complex
graphical applications will contain a number of layers (e.g. one component may be partially
covering another, etc.). Java uses these layers to track the underlying components, and
automatically ensures that the correct components are shown.
JRootPane. This is the fundamental Swing container, and forms the foundation onto which
the other layers can be placed.
The JPanel class does not possess a contents pane, etc., i.e. it is not a top level container and
offers limited functionality (it is a basic container).
The JFrame, JWindow, JApplet and JDialog classes provide public Container
getContentPane(), public Component getGlassPane(), public JMenuBar
getJMenuBar(), public JLayeredPane getLayeredPane() and public JRootPane
getRootPane() methods. Corresponding set methods are provided for the content, glass, menu
bar and layered panes (it is not possible to change the root pane).
Also note, that whilst the menubar pane is optional, the layered pane, content pane and glass
pane always exist. In what follows each of the different types of Swing container are
introduced.
PAGE
77
LECTURE 6
Whenever a frame object is declared it is not assigned a default size, nor is it visible. Hence,
before a frame can be displayed the public void setSize( int width, int height ) and public
void setVisible( boolean b ) methods should be called (sometimes the depreciated show()
method is used instead of the correct setVisible()).
The code for creating a simple frame object, and adding some components is as follows:
public class myFrame extends JFrame
{
public myFrame()
{
// Set the title of the frame
setTitle( myFrame Example );
// Specify the layout manager
getContentPane().setLayout( new BorderLayout());
// Place a button in the middle of the frame
add( someButton, BorderLayout.CENTER );
// Define the menu bar to be used
setJMenuBar( myMenuBar );
// Define the frames size and make it visible
setSize(500,250);
setVisible(true);
}
}
A dialog can be made modal, entailing that the user cannot interact with any other displayed
windows (belonging to the program) until the dialog window has been dismissed (i.e. useful
when the program cannot continue without user guidance). In contrast, non-modal dialogs can
be freely selected and deselected by the user.
A number of constructors are provided for the JDialog class, the most general is the public
JDialog( Frame owner, String title, boolean modal), which permits the dialog to be
associated with its parent frame, and the title and modal/non-modal nature of the dialog to be
specified.
As with all the top-level Swing containers, a number of methods are provided for
setting/retrieving the various panes/layout manager, etc. Apart from this, the JDialog class
provides no extra functionality (i.e. dialogs are associated with a frame, components added, and
event handlers setup).
PAGE
78
LECTURE 6
PAGE
79
LECTURE 6
The above defines the JFrame class, the JDialog class now follows:
import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*;
public class MyDialog extends JDialog
{
JSlider slider; JLabel dialogOutput; String dialogTitle;
// Provide a general constructor
public MyDialog( Frame owner, String title, boolean modal, JLabel output )
{
super( owner, title, modal );
// Store needed passed parameters
dialogOutput = output; dialogTitle = title.toString();
// Create dialog controls
slider = new JSlider( JSlider.HORIZONTAL, 0,100,50 );
slider.addChangeListener( new ChangeListener()
{
public void stateChanged( ChangeEvent e )
{ dialogOutput.setText( dialogTitle +
" : " + slider.getValue() ); }
} );
// Add them to the dialog
getContentPane().add( slider ); setSize( 300, 50 ); setVisible( true );
}
}
The above example illustrates how a JFrame object may create any number of
JDialog child windows, with each dialog sending information back to the frame
window.
Java also offers a number of JOptionPane classes, providing a means of easily and
quickly constructing dialogs. However, in those cases where the option pane offer
too simple a degree of functionality, it is necessary to extend the JDialog class.
PAGE
80
LECTURE 6
Layout Managers
By default, each container has a layout manager; an object that determines where
and how components will be displayed within the container. Whilst components
can provide size and alignment hints, it is the layout manager that has the final say
on how they are positioned (however, certain layout managers will try to
accommodate the preferred size specified by the component).
The Java platform supplies five default layout managers: BorderLayout,
BoxLayout, FlowLayout, GridBagLayout, and GridLayout. An overview of each
type of layout manager follows:
Border Layout
BorderLayout is the default layout manager for all content panes (i.e. JContentPane). A
BorderLayout has five areas available for holding components, namely, NORTH, SOUTH,
EAST, WEST and CENTER. All extra space is placed in the center area.
Box Layout
The BoxLayout manager puts components in a single row or column. The manager will ensure
that components are not sized beyond their requested maximum size.
The BoxLayout scheme can be used within a program as follows:
JFrame f = new JFrame();
p.getContentPane().setLayout( new
BoxLayout(p, BoxLayout.Y_AXIS));
p.add( new JButton( Okay );
Flow Layout
FlowLayout is the default layout manager for all JPanel objects, simply setting out components
from left to right, starting new rows when necessary, e.g.
Container contentPane = getContentPane();
contentPane.setLayout(new FlowLayout());
contentPane.add(new JButton("1"));
PAGE
81
LECTURE 6
Grid Layout
The GridLayout manager resizes the components so that they are all equal in size, and then
displays the components in the requested number of rows and columns, e.g.:
A GridLayout can be employed as follows:
contentPane.setLayout(new GridLayout(2,2));
Components are added in a left to right fashion, filling each row before moving onto the next
row.
Absolute Positioning
The examples above made use of the setLayout method to change the layout
manager used within a container. Should a null value be passed to the
setLayout method then no layer manager will be used within the container.
Instead, absolute positioning is assumed.
Absolute positioning simply entails that the programmer specifies the size
and position of a component when it is added to the container (i.e. as no layout manager is being
used, the programmer must determine where components are placed).
In general, layout managers should be used whenever possible (as they adapt to
changing font sizes, window resizes, etc.). Absolute positioning is only really
suited to those instances where the container will not be resized, nor will any of
the components within the container change (Note, as will be seen later, due to
the fact layout managers are presently incomplete, the use of absolute
positioning is widespread).
A code example follows:
PAGE
82
LECTURE 6
In the above, a number of different layout managers and containers have been employed to
produce the desired arrangement.
Practical 6
After this lecture you should explore the sixth practical pack which should enable you to
investigate the material in this lecture.
PAGE
83
LECTURE 6
Learning Outcomes
Once you have explored and reflected upon the material presented within this lecture and the
practical pack, you should:
Be capable of writing Java code that makes appropriate use of Swing containers
given a straightforward GUI problem description.
Have knowledge of the different layout managers on offer within Java, including
an understanding of how they may be appropriately used to layout components.
More comprehensive details can be found in the CSC735 Learning Outcomes document.
PAGE
84