Text Components
& Layout Managers
Peter
Komisar ©
Conestoga
College
latest
version: 5.8 2010
As with other types of Swing components, Java's text
components may be used in a simple manner
for fast
and easy deployment or in a more sophisticated fashion
that
takes advantage of the underlying Model View
Controller
architecture. In this part of the note, we take
a short tour of
the most used text components followed
by a survey of the models
that are at the heart of the
text component architecture.
//
recall model represents data, view is the visual presentation
// and controller takes view input
and applies changes to the data
JTextComponent is the
generalized parent class for a
set of text-based Swing components.
JTextComponent
defines methods commonly used in basic text
editors,
methods such as copy( ), cut( ) & paste ( ), getText( )
and
setText( ). JTextComponent supplies these and other
methods
to it's subclasses. Following is the hierarchy
of the text
components.
The
JTextComponent Hierarchy
Object
|
Component
|
Container
|
JComponent
|
JTextComponent
|
|___
JTextField
|
|___JPassword
|
|___ JTextArea
|
|___ JEditorPane
|___ JTextPane
JavaBean Property Sets
JComponents have a set
of properties that are accessible
through getXXX and setXXX( ) methods. This is part of
the JavaBean design that all Swing and AWT components
adhere to. For instance for JTextArea, properties such
as
'document', 'margin', 'caret', 'highlighter', 'keymap',
'caretColor',
'selectionColor', 'selectedTextColor',
'disabledTextColor' and 'editable' may be set or
selected.
JTextField, JTextArea
and JEditorPane are the well-used
subclasses of JTextComponent.
JPasswordField is an
extension of JTextField and and JTextPane is
an extension
of JEditorPane. To make large sections of text viewable
the simplest approach is to add the text area to a
JScrollPane.
In the following example,
explore the controls for changing
blink rate and whether a component is editable.
Code Demonstrating Getting & Setting JTextArea Properties
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
class TAProperty extends JFrame{
TAProperty(){
JTextArea jta=new JTextArea();
this.getContentPane().add(jta);
this.setSize(600,300);
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
// 'document',
'margin', 'caret', 'highlighter', 'keymap',
'caretColor',
// 'selectionColor', 'selectedTextColor',
'disabledTextColor' & 'editable'
jta.setText("\nSelected JTextArea
Properties");
jta.append("\n______________________________\n\n");
Document document =
jta.getDocument();
jta.append("Document type: " +
document + "\n");
boolean editable =
jta.isEditable();
jta.append("Is editable: " +
editable + " \n");
//
jta.setEditable(true);
editable = jta.isEditable( );
jta.append("Reset editable
property: " + editable + " \n");
Insets insets = jta.getMargin();
jta.append("Margin insets: " +
insets + "\n");
Caret caret = jta.getCaret( );
caret.setVisible(true);
jta.append("Caret description: " +
caret + "\n");
jta.append("Caret Blink
Rate: " + caret.getBlinkRate() + "\n");
//
comment
in to reset blink rate observe the change
caret.setBlinkRate(200);
jta.append("Caret Blink Rate
(after reset) : " + caret.getBlinkRate());
}
public static void
main(String[]args){
new TAProperty( );
}
}
JTextField // supports a single
line of text
One important point
to note with text components is that
setting
column widths correlates to number of field
characters
directly only for fonts with fixed widths, for
example where an
' i ' takes the same space as a 'w'.
//
column widths relate to fixed fonts
JTextField is the
component designed to accept a single line
of character
data. JTextField supports setting of text justification
with
setHorizontalAlignment( ). The three available settings are
LEFT,
CENTER, and RIGHT, where LEFT is the default.
Example
JTextField textfield =
new JTextField( );
Following are JTextField's
constructors.
JTextField
Constructors
// a JTextField based on model, text & columns
// an empty JTextField with given number of columns.
// a new TextField initialized with specified text.
//
a new TextField initialized with specified text & columns.
JTextArea // text field taken to two dimensions
JTextArea, compared to
JTextField, has the enhanced
ability to allow multiple lines
of text to be entered and
displayed in it's viewable area. It
generally would be
used for any text entry or display that would
require
more than a single line.
JTextArea has a range of
constructors, from a minimal,
'no args' constructor to one
that allows specifying some
initial text and the number of rows and
columns that will
be shown. Like other components, how JTextArea is
displayed will be influenced by the type of
layout manager
that is being used control layouts. This sometimes leads
to row and column setting being 'over-ruled' by the layout
policy.
// at
times settings seem to be 'broken' when actually the layout
// manager is overruling the user's
settings
Useful JTextArea Methods
JTextArea has a method,
setLineWrap( ) that will cause
a line to wrap instead of continuing into an
'out-of-range'
area of the component. It also has a method that will
disallow a word from being broken at a syllable. If the
argument
to setWrapStyleWord( ) is set to 'true', the
lines will be
wrapped at word boundaries. These two
useful methods are shown in the example
below.
Useful JTextArea Methods
Example
JTextArea textArea=new
JTextArea(" Comments ", 10,
30 );
textArea.setLineWrap( true);
textArea.setWrapStyleWord( true);
JTextArea
Constructors
Following is a brief summary of JTextArea( ) constructors.
// constructs a new TextArea.
// a
new JTextArea with specified document model
// a new JTextArea with model, text, rows & columns
// a new empty TextArea with specified # of rows & columns.
// constructs a new TextArea with the specified text
//
a new TextArea with the specified text, # of rows & columns.
JPasswordField
JPasswordField is
a specialization of JTextField. It masks
characters
entered into it by echoing to the field either an
asterisk or a
user defined character. The setEchoChar( )
method can be used to
set the character that is echoed in
the password field.
Example
JPasswordField password =
new JPasswordField(20);
password.setEchoChar ('^');
Following is a code sample
that shows these three
components.
Code Sample
import
javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class Text{
JTextField field;
JTextArea textArea;
JPasswordField password;
JPanel panel;
public Text() {
JFrame frame = new JFrame();
Container content=frame.getContentPane( );
panel = new JPanel();
field =new JTextField("A text field");
password = new JPasswordField(20);
password.setEchoChar ('^');
textArea =new JTextArea("A Text Area");
panel.add(field);
panel.add(password);
panel.add(textArea);
content.add(panel);
frame.setSize(200,300);
frame.setVisible(true);
}
public static void main(String[] args) {
new Text( );
}
}
JEditorPane
The JEditorPane class is
a specialization of the parent
JTextComponent. It is designed to render pages in HTML
or RTF formats. Links can be
processed with the aid of
the HyperlinkListener interface. Pages are loaded into the
editor pane using the setPage( ) method.
//
HyperlinkListener is an example of a listener class. Listeners are
// participants in
Java's
model for event processing. We cover
// listeners in the Events note.
The following code
sample is pretty primitive. If the URL is
not available no
alternative output is provided. JEditorPane
is slow and somewhat unforgiving in how it interprets page
layouts. Still it could be very useful in dedicated applications
to provide basic
interpretation of HTML pages that have been
designed to suit the component's capabilities.
Code
Sample
import
javax.swing.*;
import java.awt.event.*;
import
java.awt.*;
import java.io.*;
import java.net.*;
import
javax.swing.event.*;
class Browser extends JFrame implements
HyperlinkListener{
Browser(){
JEditorPane editorPane = new JEditorPane( );
editorPane.setEditable(false);
JScrollPane scroll = new JScrollPane(editorPane);
getContentPane().add(scroll);
URL url=null;
try {
url=new
URL(
"http://www.nytimes.com//"
);
editorPane.setPage(url);
}
catch
(MalformedURLException
mue){
System.err.println(
"
incorrect
url formatting ");
}
catch
(IOException
e)
{
System.err.println("Attempted
to
read
a bad URL: " +
url);
}
setSize(800,600);
setVisible(true);
}
public static
void main(String[]args){
new Browser();
}
//
HyperlinkListener method
as a stub
public void hyperlinkUpdate(HyperlinkEvent he){ }
}
JTextPane
JTextPane descends from
JEditorPane. A nice feature
of JTextPane is the ability to add
style to a document
using a set of attributes. A default attribute
set is available
in the form of the SimpleAttributeSet. Different
attribute
style settings are collected in the SimpleAttributeSet
object. They are set using a set of static style methods
in the
StyleConstants class. JTextPane is a full-featured
text editor that
supports formatted text, word wrap, and
image display.
// You may wish to comment out the styling
code
// to see the before after effect
Example
JScrollPane
While AWT automatically
adds scrollpanes as needed to
components, Swing requires you to add scrollpanes as they
are needed. There are
different approaches available to
supplying scrolling for visual
components. For instance, a
scrollbar can be added to a
component using the JScrollBar
class which we look at separately in a later note.
Two
Approaches to Using JScrollPane
Using JScrollPane
In Swing, scrollbars that
are added to components, only
appear
on an 'as needed' basis. For instance, scrollbars
will only
appear when the viewing area available on a text
component is
exceeded.
The most convenient
way to make a component scrollable
is to add the component
object to a JScrollPane object.
There are two ways
this can be done.
The easiest is the create a
component and pass it to
the
constructor of the JScrollPane( ).
Example
JTextArea textObject=new
JTextArea("Text");
JScrollPane pane = new JScrollPane(textObject);
Using JViewport
The other approach is to
access the particular component
that represents the viewable
area of the ScrollPane called
the JViewport. JScrollPane provides a
getViewport( )
method to get a handle to this component. Then the
component is added to the JViewport object.
Example
JViewport viewPort =
pane.getViewport( );
viewPort.add(textObject);
The
following
code
shows
the easier way and also
demonstrates
that
not
just
text components can be
scrolled.
Example
public class ScrollFrame5 extends JFrame {
public
ScrollFrame5(String
s
) {
super(s);
Icon marsIcon = new ImageIcon("balloon.jpg");
JLabel mars= new JLabel(marsIcon);
JScrollPane
scrollPane
=
new
JScrollPane(mars);
getContentPane(
).add(scrollPane,
BorderLayout.CENTER);
setSize(140,200);
setVisible(true);
}
public static void main(String[]args){
new ScrollFrame5("Map of Mars");
}
}
To
Remember When Processing ScrollBar Events
There is a bit of
obscurity that needs to be overcome when
adding action processing code to JScrollPane that isn't
present when using separate JScrollBars. JScrollPane
itself doesn't support AdjustmentListener. You
need to use
the methods, getHorizontalScrollBar( ) and or
getVerticalScrollBar( ) to get a handle to the scroll bars
objects and then add your adjustment listeners to them.
//
we
cover
event
processing later
Models Used in Text Components
Before moving onto Layout Managers we consider the
underlying
architecture of text components. Don't worry
about the details here. This is just a general overview of
how the 'pieces of puzzle' fit together.
The Java text components
use a MVC or Model View
Controller architecture. The model used
in Swing text
components is an implementation of the
Document interface.
The 'Controller' is represented by an
implementation of
the abstract, EditorKit class. The 'View' is
provided by
an object returned by the UIManager.
The
Document Interface
//
not to be confused with the Document Interface!
The Document interface
found in the javax.swing.text
document has a custom model based on a tree data
structure useful for describing the hierarchical aspects
of a document.
There is also a Document
Interface defined in the
org.w3c.dom package which is an implementation of
the W3C's XML Document model. This is an entirely
separate model from the one used in Swing.
Java's
Document
Object
serves
as the 'model' in the
MVC architecture The
'document', in Java, is a class
that
implements the Document interface. The Document
interface
supplies a container for text for everything from
very simple plain
textfields to complex documents like
XML or HTML pages.
At
it's
simplest, a component's content, as
described by
the document object, is a sequence of Unicode
characters
which starts at the offset 0. A range corresponding to
'Detroit' may be thought of as the space before and after
a set of characters. For Detroit the range is described as
0 - 7 .
Example of a Range // Detroit has the range 0 to 7
D
e t r o i t
C i t y
0 1
2 3 4 5 6 7 8 9
10 11 12
Abstract
document
defines
methods
such as getLength( ),
getText( int, int ) and getText(int,int,segment)
to access
groups of characters
that makes up a document object's
content.
The
following code just shows how the characters represented
in a text component are a view of the document model here a
text string that is the data behind the view.
Using a Few AbstractDocument Methods
Element Objects
// the large parts of a hierarchical data
structure
The
document stores textual content in 'Element' objects.
A paragraph, for instance, may be
represented as an
Element
object.
An
element is
an object of a class that implements the
Element interface. The
Element interface contains methods
that describe how an object can be related to another in
the larger
document structure. The
getDefaultRootElement( )
and getRootElements( ) provide
access to the elements of
a document's
structure.
An Example of a Document's Hierarchy of Element Object
Course
/
\
Unit1
Unit2
/
\
Section1
Section2
/
\
Paragraph1
Paragraph2
// where nodes
are implementations of the Element interface
Adding
and
removing
text
is referred to as mutating the
document. Document
mutation is accomplished using
the
methods of the Document interface, insertString( ),
remove( )
and createPosition( ).
In addition to standard
editing capabilities, the Swing
text components also supply 'undo'
and 'redo' capability
and action processing based on caret changes.
References for further
investigation
http://java.sun.com/products/jfc/tsc/articles/text/element_interface/
http://web.mit.edu/swing_v1.1/swing-1.1beta2/doc/api/com/sun/java/swing/text/Document.html
Document
Implementations
Following
is
a
description
of the hierarchy and relationships
between the different Document classes and the interfaces
they
implement. The AbstractDocument
class implements
Document. AbstractDocument is subclassed to
PlainDocument
and DefaultStyledDocument.
DefaultStyledDocument
implements
a Document sub-interface
called StyledDocument. HTMLDocument is a subclass of
DefaultStyledDocument. A diagram is the
best way to show
these relationships.
Document Hierarchy
Abstract Document
implements
Document
_________|_________
|
|
PlainDocument
DefaultStyledDocument implements
StyledDocument
|
HTMLDocument
The
text components all have the simple PlainDocument for a
document
model except for JTextPane.
JTextPane by default
has DefaultStyledDocument as it's document
model. Even the
JEditorPane has
PlainDocument set as it's default model.
The
document model used with a component can be changed
in a number of
ways. If the setPage( ) method is
used with a
text component the document model may change
depending
on what the file format is of the
page that is being set. The
document can also be
changed using the setDocument( )
method. The component's constructors
can also be used to
specify a
particular Document type.
Layout
Managers
Peter Komisar © Conestoga College
Early
Problems With GUI Portability
AWT
introduced
Layout
Managers
to assist in laying out
components in GUIs. Layout managers avoid the
use of
absolute values and adopt strategies that assist in porting
Java GUIs across platforms.
Swing components, which
are painted superficially on a
single native base component now make the use of an x, y
coordinate placement more viable as individual peer-based
components are not insisting on particle sizes. One
downside
to using x, y coordinates to place components is that the
resizing behavior of layout managers is lost. If required
the
programmer can supply this behavior.
Once
a programmer is familiar with Java's layout managers,
almost any layout can
be created. It may be daunting at first
to get things exactly as you would like them.
The
three most common AWT layouts are:
GridBagLayout
is
purported
to
be the manager most often
used
'behind the scenes' in commercial IDEs
and visual
GUI builders. Swing introduces a number of new layouts
but these are custom designed and
associated with single
Swing components. One new layout, BoxLayout is a useful
in addition for GUI design.
No Layout & Custom LayoutManagers
Following are
different layout strategies that can be taken
for
laying
out
components.
It use to be with AWT that using
a null layout was not recommended as creating an absolute
grid with peer-based components might create unpredictable
results when porting between platforms.
Now with
Swing's peerless components using a fixed grid
seems to be a viable approach, particularly if you do the
grid on a peerless component that you add to the peer-based
container.
No LayoutManager
Using no layout is
possible. No layout allows the use of
a grid which can be customized exactly as required. One
can use absolute coordinates to place components. In order
to disable any default layouts, the container's
layout is set to
null creating the situation where
no layout manager is active.
This is done
using the setLayout( ) method.
Example
component.setLayout(null);
Nulling
the
Layout
Allows
setSize ( ) and setBounds( ) To Work
This
will lead to calls like setSize( ) and setBounds( )
being
enabled and allowed to work. Normally these methods do not
function as they are overridden by the
layout managers. With
no layout, positioning components is left
to the
programmer,
including any activity that is needed if the
container is re-sized.
This requires
overriding the container's setBounds( ) method.
Normally
only
setBounds( ) is used as setSize( ) just calls
setBounds( ). Following
is some code which shows a null
layout being used.
Null Layout Code Sample
class
NoLayout extends JFrame{
NoLayout(String s){
super(s);
JPanel panel=new JPanel();
// here's a panel's
layout is set to null
panel.setLayout(null);
JLabel
label=
new
JLabel("A Label");
// here is
a component having it's bounds being set
label.setBounds(40,20,120,20);
panel.add(label);
JTextField text=new JTextField("A loaded textfield");
text.setBounds(40,70,120,20);
panel.add(text);
JTextArea textArea=new JTextArea(" Some text \n in a text
area");
textArea.setBounds(40,120, 120, 50);
panel.add(textArea);
getContentPane().add(panel,BorderLayout.CENTER);
setSize(250,250);
setVisible(true);
}
public static
void main(String[]args){
new NoLayout("A frame set to a null layout");
}
}
//
the convenience of a null layout is fine grained control of a layout.
// The downside is this layout will not re-size.
Creating Custom Layout Managers
The
common layout managers supplied by the Java
AWT API are
implementationsof two interfaces:
For
most of us, it will be more convenient to use stock
layout managers or no layout managers at
all.
Border, Flow & Grid Layout Managers
Overloaded
add(
)
Methods
of
Container Class
All components
inherit overloaded versions of the add( )
method, which will allow variations on how sub-components
are added to containers. Two of these add methods allows
specifying an index, which allows placing a component in
a particular compartment of a layout grid. The simpler of
the two is exampled below.
Example
add (Component comp,
int index)
BorderLayout
A
Border Layout divides a container's into
five regions,
north, south, east, west, and center. Each region is
has a corresponding constant, NORTH, SOUTH,
EAST,
WEST, and CENTER. When
adding a component to a
container with a Border Layout, use one of
these five
constants as in the following example.
Example
Panel
p
=
new Panel();
p.setLayout(new BorderLayout( ));
p.add(new Button("Okay"), BorderLayout.SOUTH);
BorderLayout
interprets
the
absence
of a string specification
the same as the
constant CENTER.
Example
Panel
p2
=
new Panel( );
p2.setLayout(new BorderLayout());
p2.add(new TextArea());
// Same as p.add(new TextArea(), BorderLayout.CENTER);
BorderLayout Example
import
javax.swing.*;
import java.awt.*;
class f extends JFrame{
f(){
add(new
Button("NORTH"),BorderLayout.NORTH);
add(new
Button("SOUTH"),BorderLayout.SOUTH);
add(new
Button("EAST"),BorderLayout.EAST);
add(new
Button("WEST"),BorderLayout.WEST);
add(new
Button("CENTER"),BorderLayout.CENTER);
// center is the default add
setSize(800,600);
setVisible(true);
}
public static void
main(String[]args){
new f( );
}
}
Just
For
Reference
BorderLayout supports
four relative
positioning
constants.
These four are BEFORE_FIRST_LINE,
AFTER_LAST_LINE,
BEFORE_LINE_BEGINS, and
AFTER_LINE_ENDS. In
a container set to
ComponentOrientation.LEFT_TO_RIGHT,
these constants map to
NORTH,
SOUTH, WEST and EAST,
respectively. Mixing
the two types of constants can lead to
unpredictable results and should
be avoided.
FlowLayout
A
flow layout arranges components in a left-to-right flow,
top-to-bottom centering as it goes.
It works much like a text
editor that has been set to center text.
Flow layouts are often
used to
arrange buttons in a panel. It will center buttons left
to
right until no more buttons fit on the same
line. Each line
is centered. Flow layout has
three constructors that can be
used to effect alignment and
inter-component spacing.
Flow
Layout
provides the constants, CENTER, LEFT,
RIGHT, LEADING
and TRAILING, used to control how
components are aligned. LEADING
will cause components
to line up with
the component on the left above it. Trailing
causes lining up to the right on the vertical axis.
Flow
Layout Constants
The
layouts use
int values to add pixels of space
between
the components in both the horizontal and vertical
directions.
Flow Layout will as much as
is possible allow components
to retain their
preferred size and shape.
FlowLayout
Constructors
allow
specifying
alignment and
the gap between components. The default is 5 pixels in
both dimensions.
FlowLayout
Constructors
FlowLayout
can also use the overloaded version of the
add( ) method to insert a
component at a particular index
in the list
of components being added.
Example
flow.add(new JButton(" Inserted at 5 by offset 4 ") , 4 );
Following
is
a
code
sample that shows the FlowLayout
class in action.
FlowLayout Sample
import
javax.swing.*;
import
java.awt.*;
class
Ed3 extends JFrame{
JButton
j1,j2,j3,j4,j5,j6,j7,j8,j9;
Ed3(){
JPanel
flow=new
JPanel();
flow.setLayout(new
FlowLayout(FlowLayout.LEADING,10,20));
// try it with
trailing to see the difference
JButton[] buttons=new JButton[]
{
j1,j2,j3,j4,j5,j6,j7,j8,j9
};
String[]
names=
{"One
","Two
","Three","Four
","Five
",
"Six
","Seven","Eight","Nine
"};
for(int
i=0;i<9;i++){
buttons[i]
=
new
JButton(names[i]);
buttons[i].setFont(new
Font("Monospaced",Font.ITALIC|Font.BOLD,14));
flow.add(buttons[i]);
}
getContentPane().add(flow);
JLabel
label=new
JLabel("Flow
Test");
getContentPane().add(label,
BorderLayout.NORTH);
setSize(400,300);
setVisible(true);
}
public
static
void
main(String[]args){
Ed3
ed=new
Ed3(
);
}
}
GridLayout
// opposite to flowlayout with respect to preferred size
GridLayout
is
opposite
to FlowLayout which respects
the preferred size of components. GridLayout causes
a component added to one of it's grid elements to fill
that element.
The
GridLayout class is a layout manager that lays out
a container's
components in a rectangular grid.
The
container is divided into equal-sized rectangles, and one
component is placed in each
rectangle. The number of
rows and columns can be specified as
integers to the
constructor or set
with the methods setRows( ) and
setColumns( ) .
Example
setLayout(new GridLayout(3,2));
// sets the layout to a grid of three rows and two columns.
If
the number of rows and the number of columns have
not been specified,
(using the no-args constructor of
GridLayout) the layout creates enough columns to show
the
number of components that have been added.
If the
row is specified then the required number
of columns is
calculated. The columns will also be adjusted even if
specified. For example, if three
rows and two columns
have been specified and nine components
are added to
the layout, then they will be
displayed as three rows of
three columns.
Specifying
the
number
of
columns affects the layout only
when the number of rows
is set to zero.
//
rows are fixed while columns vary
Card & GridBagLayout
CardLayout
The
behavior of card layout has been supplanted by the
easy to use
JTabbedPane Swing component.
JTabbedPane
is also recommended for changing screens inside a GUI.
CardLayout is available for your use and is
your only
choice for this type of behavior if
restricted to AWT.
This might be the case in using Applets and
maintaining
compatibility with
browser using older Java Development
Kits.
CardLayout
treats
each
component
in the container as a
card. Only one card is
visible at a time, and the container
acts as a stack of cards. The first component added to a
CardLayout object is the visible component
when the
container is first displayed. The ordering
of
cards
is
determined by the container's own internal ordering of
its
component objects. CardLayout
defines a set of methods
that allow an application to flip through
the cards in order,
or to show a specified
card.
CardLayout's
addLayoutComponent(
) method
can be
used to associate a string identifier with a given card
for
fast access.
//
precursor of the layering behavior that was added to JFrame
GridBagLayout
// a 'dynamic' grid
GridGagLayout takes the
idea behind the GridLayout
manager and adds variability to the size of each grid cell.
Where a grid
layout is fixed to a uniform grid of rows and
columns, GridBagLayout
allows different properties to
be added to each grid element so
the elements can be
arranged in flexible asymmetrical patterns.
The JDK
documentation refers to it as a 'dynamic' grid.
The
properties used to effect how each cell of the grid is
presented is
stored in a GridBagContraints class. The
following
GridBagContraints constructor shows the
properties
that the GridBagConstraint class contains. The lower case
fields can have a value assigned to them while those that
are all
uppercase signal they are constants. The constraints
that can be
assigned values can all be passed into the
second of
GridBagConstraints constructors which is
shown below.
GridBagConstraints
Constructors
public
GridBagConstraints( )
// The no-args versions sets all the constraints to default values
public
GridBagConstraints
(
int
gridx,
// the cell at the left of the component's display area
int gridy,
//
the
cell
at the top of the component's display area,
int gridwidth,
// # of cells in a row for the
component's display area.
int gridheight, //
# of cells in a column for the component's display area.
double weightx,
// specifies how to distribute extra horizontal space.
double weighty,
// specifies how to distribute extra vertical space.
int anchor, //
locates the component when it is smaller than it's display area
int
fill,
// used to size a component to
an area
Insets insets, //
min space between the component & display area edges.
int ipadx, //
specifies space to add to the minimum width of the component.
int ipady //
specifies space to add to the minimum height of the component
)
GridBagConstraint
Constants
In
addition to the assignable values of the GridBagContraints
class,
there are a large number of
constants whose chief
tasks include locating elements in the grid bag
layout. They
include directional constants
like NORTH, SOUTH, EAST,
WEST, NORTHEAST,
NORTHWEST, SOUTHEAST, and
SOUTHWEST. There is also
a CENTER constant.
HORIZONTAL
causes
resizing
horizontally
but
not vertically.
VERTICAL is opposite
to HORIZONTAL. NONE is used to
specify a
component will not be resized. REMAINDER makes
it's component
the last component in its column or row.
RELATIVE specifies a
location that is either next to last or
next to previous.
The GridBagLayout class
has a single no args constructor.
It defines two versions of
addLayoutComponent( ) to add
a component to the grid bag and
associate it with a
particular GridBagContraint object. In a grid
bag the area
that is assigned to each component occupying a cell
in
the grid is called the component's display area.
The
GridBagConstraint object dictates how the component
will be shown in
it's display area. How the components are
displayed will be
influenced by the component's container.
GridBagConstraint
objects are customized by setting one
or more of it's instance
variables.
The constraint object
for any component can be retrieved
using the GridLayout's
getConstraints( ) method. The
setConstraints( ) method is used to
set constraints on a
component before it is added to the layout.
Observation of the Effects of the GridBagConstraint Properties
GridBagLayout can at
first be difficult to understand. It
uses a popular metaphor where
a set of objects are defined
and then constraints are applied to them
to control their
behavior. Looking at each constraint property
in isolation
helps to unravel it's secrets. If the fill is set to
'both', the
components will fill the zones they occupy in both
horizontal
and vertical directions. If no 'fill' is assigned and
weight
values are set to zero the components will assume their
preferred size.
With even a small weight
assignment the
components
will fill their areas. The ipadx and ipady variables
increase
the size of components incrementally in pixels from their
preferred sizes. Using the relative and remainder variables
specifies a relationship between two components in how
they divide
a row. The gridwidth and gridheight can be used
to specify the
number of rows or columns that a component
occupies.
Whatever changes are
made before the setConstraints( )
method is called, are applied.
In code below, a text area
is set to a grid height of 6.
Example
constraints.gridheight=6;
Six buttons
that are added next and have gridheights of
just 1. They are then
set to take up the remainder of their
rows with the next line.
Example
constraints.gridwidth =GridBagConstraints.REMAINDER;
This way 6 buttons share
the same vertical space as the
text area component at the bottom of
the GUI.
Basic
GridBag Strategy
The basic approach to
using GridLayout is to first create
a GridLayout and set it to a container using the setLayout( )
method. Then a
GridBagConstraint
object is created. It's
variables are assigned values
and the setConstraints( )
method is called to set theses constraints
to the components.
The components are then added to the
container. After
adding, the constraints object can be changed to
effect
new changes on the next components that will be added
to the
container.
// comments in red in the following code sample may make this clearer
GridBagLayout
Code Sample
Following
is
a
GridBag
sample that shows many of the
constraints in action.
This is done in classic AWT. To
convert this class to Swing all the components would
go
to their 'J' form counterparts. The javax.swing package
would need to be
imported. Then JFrame would need
require the use of getContentPane( ) for setting the
layout
and adding components.
GridBagLayout Example
Many authors and Java
programmers have their own favorite
'recipes' for using GridBag
layout which attests to it's great
power and flexibility.
It is important if you
need to use the GridBag Layout to check
the JDK documentation on how each facet of the constraint
class works.
New Swing Layouts
BoxLayout
The
Swing API adds a number of new layouts. Most are
custom designed for
specific components and are not
made for the general utility of
the GUI programmer. One
that is accessible is the BoxLayout. The
BoxLayout
interface can be implemented
or the Box component used
which provides a default
implementation of the BoxLayout.
BoxLayout
allows
multiple
components
to be layered out
either vertically or
horizontally. The components will
not
wrap so, for example, a vertical arrangement of components
will
stay vertically arranged when the frame is
resized.
Nesting
multiple
panels with different combinations
of
horizontal and vertical can create an effect similar to
GridBagLayout. You can nest multiple
boxes and add
components to them to get the arrangement you want.
//
nesting BoxLayouts yields flexible layouts similar to GridBagLayout
When
you create a BoxLayout, you specify
whether its
major axis is the X axis, ( horizontal )
or Y axis, ( vertical ).
Components are arranged from left to
right (or top to bottom),
in the same order as they were added to
the container.
The
Box Class
Instead
of
using
BoxLayout
directly, many programs use
the Box class.
The Box class provides a lightweight
container that uses a BoxLayout. Box also provides
handy
methods to help you use BoxLayout well.
BoxLayout
attempts
to
arrange
components at their
preferred widths (for left to
right layout) or heights (for
top to
bottom layout). For a left to right layout, if not
all the
components are the same height, BoxLayout
attempts to make all the components as
high as the
highest component. If that's not possible for a
particular
component, then BoxLayout
aligns that component
vertically, according to the component's Y
alignment.
//
Y layouts are uniform in width, X layouts are uniform in height
By
default, a component has an Y
alignment of 0.5, which
means that the vertical
center of the component should
have the same Y coordinate as the
vertical centers of
other components
with 0.5 Y alignment. //
from
the
JDK
API
Similarly,
for
a
vertical
layout, BoxLayout attempts to
make all components in
the column as wide as the widest
component; if that fails, it aligns them horizontally
according
to their X alignments.
Struts
& Glue
A strut can be used to
place a fixed amount of space
between two components. Struts can
be set with the
createHorizontalStrut( ) or createVerticalStrut( ) methods.
A
rigid area is an an invisible component that always
takes up the
same amount of space and is created using
the createRigidArea( )
method. Glue is a flexible area
that is created with the createGlue(
) method.
The
create methods for glue and struts create flexible and
rigid areas
that, when resized, will re-size
proportionately
or remain fixed in size respectively.
Resize the following and
you will see the rigid areas
between the two middle labels remains unchanged
while the glue parts re-size with the container.
Box Code Example
import javax.swing.*;
1) Which of
the following is able to display RTF files
a) JPasswordField
b)
JTextField
c)
JTextArea
d)
JEditorPane
2) What is the name, in
Java, of the component that is used to represent sub-sections
of a document?
a) Blocks
b)
Paragraphs
c) Elements
d) Lines
3) Which of the
following layout managers is effectively replaced by JTabbedPane
a) BoxLayout
b)
FlowLayout
c) GridLayout
d) CardLayout
4) True or False.
Absolute x-y coordinate based layouts are possible using the
NullLayout manager.
5) Which of the following statements regarding BorderLayout is least correct?
a) Any region that is
left out will be filled by the CENTER region if the CENTER
region is added.
b) Using the getContentPane( ).add( ) with a
component and not specifying a region
will by
default add to the center.
c) If a second components is added to
a region where another component is already
resident, the second component added is ignored.
d) BorderLayout
has the constants, NORTH, SOUTH and CENTER.
6) Which of the
following layouts is a swing layout rather than an awt layout?
a)
GridBagLayout
b) CardLayout
c) BoxLayout
d) CardLayout
7) Which of the
following statements is not correct?
a) GridLayout will
adjust the number of columns depending on the number of
components added to the grid.
b) GridLayout allows components to
retain their preferred size and shape.
c) GridLayout is used to
create rows and columns in uniform grid
d) GridLayout is one of
the AWT layout managers.
8) Regarding
BoxLayout which statement is not correct?
a) Box Layout allows
the creation of a set of components along a horizontal
or vertical access.
b) BoxLayout allows the creation of rigid
areas.
c) BoxLayout allows the creation of flexible area.
d)
BoxLayout allows the creation of rows and columns.
Exercise
Create in 5 JPanel
classes an example of each of the following.
a)
A null layout
b)
A flow layout
c)
A grid layout
d)
A border layout
e)
A box layout
Each
panel should have their layouts set using setLayout( ) and
populated
with a mixture of JLabels, and JTextComponents that
clearly
show the mapping strategy that each layout supplies.
You
can use a 'LayoutRunner' class that extends JFrame to hold
and
display these
panels. You could add the instantiations and add methods
to
load them all into the runner class. Use commenting to cause anyone
of them to show
to screen.
You can also make nest
them all in a single grid layout so they all
are visible at once. You might use a container set to a border layout.
Inside it's center region create a panel set to a 4 x 4 grid which then
will nest the other four variations.
Finally you can used
JTabbedPane to hold each of the variations.
Anyone one approach will do.
//
Later when we cover event processing we might add buttons that
//
allow selection of the various panels within the same GUI window.
If possible supply screen
shots of your layouts with your submissions.
Optional
Add a gridbag layout
to the list above