Download as pdf or txt
Download as pdf or txt
You are on page 1of 11

LECTURE 6

Java Swing Containers


Contents of lecture 6:
1.

Containers within Java

Overview of Container functionality


Different container types within Java

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.

public abstract class Container extends Component


The Container class provides the following useful methods (in addition to those inherited from
the Component class).

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

Painting and drawing on Containers


Whilst a container inherits the paint/update, etc. methods of the component class, within the
Container class refined versions of these methods are made available.
In particular, the public void update( Graphics g ) and public void paint( Graphics g )
methods ensure that any lightweight components (i.e. Swing components) contained within the
container are told to render themselves (i.e. the component should
draw itself on the screen). Should the programmer override the
containers paint method, then it is important they call
super.paint(g) to ensure lightweight components will be
correctly drawn inside the container.

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.

public class JFrame extends Frame


A JFrame is a window that contains a
title bar, menubar and a border.
Furthermore, frames are reduced to an
icon if minimised.
The JFrame class extends the normal
AWT Frame by simply adding various
methods for setting and retrieving the
different panes. In turn the Frame class
defines a number of useful methods,
including public void setIconImage(
Image image ), public Image
getIconImage(), public boolean
isResizable() and public void
setResizable( boolean resizable ).

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);
}
}

public class JDialog extends Dialog


Dialog windows are suited to those instances where some information must be
gleamed from the user (often in situations where the program cannot continue until it
receives further instructions). Some example dialog windows follows

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

Example of JFrame/JDialog usage


The following example will develop a JFrame application that can spawn any number of
JDialog children. Each child dialog will contain a JSlider, which the user can vary between 0
and 100. Any changes in the sliders value will be output by the JFrame parent, e.g.:

import java.awt.*; import java.awt.event.*; import javax.swing.*;


public class MyFrame extends JFrame
{
int iNumFrames=0; JLabel outputLabel; JButton startButton;
// Construct GUI, add action listener
public MyFrame()
{
outputLabel = new JLabel();
startButton = new JButton( "Start" );
startButton.addActionListener( new ActionListener()
{ public void actionPerformed( ActionEvent event )
{ createDialog(); }
} );
getContentPane().add( outputLabel, BorderLayout.CENTER );
getContentPane().add( startButton, BorderLayout.SOUTH );
setSize( 300, 100 ); setVisible( true );
}
// Create and display a new dialog box
private void createDialog()
{
String dialogTitle = "Dialog [" + (iNumFrames++) + "]";
MyDialog newDialog = new MyDialog( this, dialogTitle, false, outputLabel );
}
// Start the application and add a window close handler
public static void main( String args[] )
{
MyFrame frameInstance = new MyFrame();
frameInstance.addWindowListener(
new WindowAdapter()
{
public void windowClosing(WindowEvent e )
{ System.exit( 0 ); }
}
);
}
}

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.

public class JWindow extends Window


A JWindow is a container that can be displayed anywhere on the screen (i.e. it is a top level
container). However, unlike a frame, a window does not have a title bar,
window-management buttons, or the other attractive features of a frame.
Hence, a JFrame should be used whenever a fully featured window
(including menu, close buttons, etc.) is needed. A JDialog should be used
whenever some input is needed from the user. A JWindow object is really
only suited to those few applications where some simple, additional
information needs to be displayed to the user (e.g. pop-up menus).

JApplets and JPanels


JApplets and JPanels are not considered here. It is assumed the earlier Java programming
course has explored them in sufficient detail.

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.

A BorderLayout can be employed as follows:


Panel p = new Panel();
p.setLayout( new BorderLayout() );
p.add( new JButton( Ok ), BorderLayout.SOUTH );

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.

Grid Bag Layout


This is the most sophisticated layout manager, permitting a grid to be formed (a number of rows
and columns), inside which components can be aligned and permitted to span more than one cell:
The GridBagLayout class requires that a
corresponding GridBagConstraints object be
created, defining how components are to be
placed within the container. Further details can
be found on Suns Java site.

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:

Container contentPane = getContentPane();


contentPane.setLayout(null);
b1 = new JButton("one");
contentPane.add(b1);
b1.setBounds( 25, 5, 75, 20);

PAGE

82

LECTURE 6

Combining Layout Managers


The real power of using layout managers arises when they are combined together. Consider the
following GUI:

Which can be constructed as follows:


JFrame object using FlowLayout and containing two
JPanel objects

JPanel using GridLayout, containing


3 JCheckBox objects

JPanel using BorderLayout,


containing a JTextArea and a JButton

In the above, a number of different layout managers and containers have been employed to
produce the desired arrangement.

Providing hints about a components size


Sometimes it is necessary to provide hints to the layout manager as to how components should
be set out (to ensure the desired arrangement is formed). Java provides a number of methods
towards accomplishing this, namely:

setMinimumSize, setPreferredSize, and setMaximumSize can be used to specify the


components minimum, preferred and maximum size.
setAlignmentX and setAlignmentY methods can be used to control where the component
should be located.
Note, presently, only the BoxLayout manager pays any attention to alignment hints.

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:

Have knowledge of Javas container class hierarchy, including the


functionality offered by each Swing container and the roles for which
individual Swing container are particularly suited.

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.

Be capable of writing Java code that successfully arranges components given a


straightforward component layout design.

More comprehensive details can be found in the CSC735 Learning Outcomes document.

PAGE

84

You might also like