Professional Documents
Culture Documents
Sun Press - SL-320 - GUI Construction With Java Foundation Classes
Sun Press - SL-320 - GUI Construction With Java Foundation Classes
Foundation Classes
SL-320
Student Guide
Enterprise Services
MS BRM01-209
500 Eldorado Blvd.
Broomfield, Colorado 80021
U.S.A.
Copyright 1998 Sun Microsystems, Inc. 901 San Antonio Road, Palo Alto, California 94303, U.S.A. All rights reserved.
This product or document is protected by copyright and distributed under licenses restricting its use, copying,
distribution, and decompilation. No part of this product or document may be reproduced in any form by any means
without prior written authorization of Sun and its licensors, if any.
Third-party software, including font technology, is copyrighted and licensed from Sun suppliers.
Parts of the product may be derived from Berkeley BSD systems, licensed from the University of California. UNIX is a
registered trademark in the U.S. and other countries, exclusively licensed through X/Open Company, Ltd.
Sun, Sun Microsystems, Solaris, the Sun Logo, Java, JDK, JavaBeans, the Java Logo, PersonalJava, JavaSoft, and 100% Pure
Java are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
All SPARC trademarks are used under license and are trademarks or registered trademarks of SPARC International, Inc.
in the U.S. and other countries. Products bearing SPARC trademarks are based upon an architecture developed by Sun
Microsystems, Inc.
The OPEN LOOK and Sun Graphical User Interface was developed by Sun Microsystems, Inc. for its users and licensees.
Sun acknowledges the pioneering efforts of Xerox in researching and developing the concept of visual or graphical user
interfaces for the computer industry. Sun holds a non-exclusive license from Xerox to the Xerox Graphical User Interface,
which license also covers Suns licensees who implement OPEN LOOK GUIs and otherwise comply with Suns written
license agreements.
U.S. Government approval required when exporting the product.
RESTRICTED RIGHTS: Use, duplication, or disclosure by the U.S. Govt is subject to restrictions of FAR 52.227-14(g)
(2)(6/87) and FAR 52.227-19(6/87), or DFAR 252.227-7015 (b)(6/95) and DFAR 227.7202-3(a).
DOCUMENTATION IS PROVIDED "AS IS" AND ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS,
AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH
DISCLAIMERS ARE HELD TO BE LEGALLY INVALID.
Copyright 1998 Sun Microsystems Inc., 901 San Antonio Road, Palo Alto, California 94303, Etats-Unis. Tous droits
rservs.
Ce produit ou document est protg par un copyright et distribu avec des licences qui en restreignent lutilisation, la
copie, la distribution, et la dcompilation. Aucune partie de ce produit ou document ne peut tre reproduite sous aucune
forme, par quelque moyen que ce soit, sans lautorisation pralable et crite de Sun et de ses bailleurs de licence, sil y en a.
Le logiciel dtenu par des tiers, et qui comprend la technologie relative aux polices de caractres, est protg par un
copyright et licenci par des fournisseurs de Sun.
Des parties de ce produit pourront tre drives du systmes Berkeley 4.3 BSD licencis par lUniversit de Californie.
UNIX est une marque dpose aux Etats-Unis et dans dautres pays et licencie exclusivement par X/Open Company Ltd.
Sun, Sun Microsystems, le logo Sun, Solaris, Java, JDK, JavaBeans, le Java Logo, PersonalJava, JavaSoft, et 100% Pure Java
sont des marques de fabrique ou des marques dposes de Sun Microsystems, Inc. aux Etats-Unis et dans dautres pays.
Toutes les marques SPARC sont utilises sous licence sont des marques de fabrique ou des marques dposes de SPARC
International, Inc. aux Etats-Unis et dans dautres pays.
Les produits portant les marques SPARC sont bass sur une architecture dveloppe par Sun Microsystems, Inc.
Linterfaces dutilisation graphique OPEN LOOK et Sun a t dveloppe par Sun Microsystems, Inc. pour ses
utilisateurs et licencis. Sun reconnat les efforts de pionniers de Xerox pour larecherche et le dveloppement du concept
des interfaces dutilisation visuelle ou graphique pour lindustrie de linformatique. Sun dtient une licence non exclusive
de Xerox sur linterface dutilisation graphique Xerox, cette licence couvrant galement les licencis de Sun qui mettent
en place linterface dutilisation graphique OPEN LOOK et qui en outre se conforment aux licences crites de Sun.
Laccord du gouvernement amricain est requis avant lexportation du produit.
Le systme X Window est un produit de X Consortium, Inc.
Please
Recycle
Please
Recycle
Contents
About This Course.......................................................................................xi
Course Overview ............................................................................... xii
Course Map....................................................................................... xiii
Module-by-Module Overview ........................................................ xiv
Course Objectives........................................................................... xviii
Skills Gained by Module................................................................... xx
Guidelines for Module Pacing ....................................................... xxii
Topics Not Covered....................................................................... xxiii
How Prepared Are You?............................................................... xxiv
Introductions .................................................................................... xxv
How to Use Course Materials ...................................................... xxvi
Course Icons and Typographical Conventions ....................... xxviii
Icons ....................................................................................... xxviii
Typographical Conventions ..................................................xxix
Introduction ................................................................................................1-1
Relevance............................................................................................ 1-2
Objectives ........................................................................................... 1-3
Course Contents ................................................................................ 1-4
What Is JFC?....................................................................................... 1-5
What is Swing? .................................................................................. 1-7
Printing ............................................................................................... 1-8
Why Not Use AWT? ......................................................................... 1-9
What Should a Replacement for AWT Offer?............................. 1-11
General Features .....................................................................1-11
Performance Features.............................................................1-14
Platform Independence Features..........................................1-15
Costs of Using JFC/Swing............................................................. 1-17
Exercise: Investigate Swing Component set ............................... 1-18
Preparation...............................................................................1-18
Tasks .........................................................................................1-18
Exercise Summary...................................................................1-19
Check Your Progress ...................................................................... 1-20
Think Beyond .................................................................................. 1-21
i
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Swing Foundations....................................................................................2-1
Relevance............................................................................................ 2-2
Objectives ........................................................................................... 2-3
Comparing Swing and AWT Components ................................... 2-4
Naming and Event Model .......................................................2-4
Selecting Swing or AWT ..........................................................2-5
Converting From AWT to Swing.................................................... 2-6
New Components in Swing............................................................. 2-7
Top-Level Swing Containers ........................................................... 2-8
Using a RootPaneContainer.......................................................... 2-9
Overview ....................................................................................2-9
The Root, Glass, and Layered Panes ....................................2-10
JFrame Essentials............................................................................ 2-11
Background..............................................................................2-11
Reacting to the System Menu................................................2-12
Exercise: Converting an AWT GUI to Swing.............................. 2-13
Preparation...............................................................................2-13
Tasks .........................................................................................2-13
Exercise Summary...................................................................2-14
Check Your Progress ...................................................................... 2-15
Think Beyond .................................................................................. 2-16
Basic Swing Components.........................................................................3-1
Relevance............................................................................................ 3-2
Objectives ........................................................................................... 3-3
Overview ....................................................................................3-4
Creating an Icon.......................................................................3-5
Implementing the Icon Interface ...........................................3-6
The JLabel Class .............................................................................. 3-7
Overview ....................................................................................3-7
JLabel Example........................................................................3-8
Tooltips ............................................................................................... 3-9
Buttons.............................................................................................. 3-10
The JButton Class .......................................................................... 3-11
Overview ..................................................................................3-11
JButton Example....................................................................3-12
The JCheckBox Class...................................................................... 3-14
Overview ..................................................................................3-14
JCheckBox Example ...............................................................3-15
The JRadioButton Class ............................................................... 3-16
Overview ..................................................................................3-16
JRadioButton Example.........................................................3-17
The JComboBox Class...................................................................... 3-19
Overview ..................................................................................3-19
JComboBox Example ...............................................................3-20
The JMenu Class .............................................................................. 3-22
ii
Overview ..................................................................................3-22
JMenu Example ........................................................................3-23
Additional Features of JMenu........................................................ 3-25
Keyboard Accelerators ...........................................................3-25
Menu Positioning ....................................................................3-26
Exercise: Using Basic Swing Components .................................. 3-27
Preparation...............................................................................3-27
Tasks .........................................................................................3-27
Exercise Summary...................................................................3-28
Check Your Progress ...................................................................... 3-29
Think Beyond .................................................................................. 3-30
More Swing Foundations .........................................................................4-1
Relevance............................................................................................ 4-2
Objectives ........................................................................................... 4-3
JComponent Accessibility ................................................................ 4-4
Actions ................................................................................................ 4-6
Keystrokes.......................................................................................... 4-8
Attaching an Action to a KeyStroke ............................................ 4-9
Exercise 1: Investigate Action Objects ........................................ 4-11
Preparation...............................................................................4-11
Tasks .........................................................................................4-11
Exercise 2: Investigate Keystroke Handling................................ 4-12
Preparation...............................................................................4-12
Tasks .........................................................................................4-12
Exercise Summary........................................................................... 4-13
Check Your Progress ...................................................................... 4-14
Think Beyond .................................................................................. 4-15
JDK 1.2 Printing .........................................................................................5-1
Relevance............................................................................................ 5-2
Objectives ........................................................................................... 5-3
Two Modes of Printing .................................................................... 5-4
JDK 1.2 Printing................................................................................. 5-5
Implementing the Printable Interface ........................................ 5-6
Using the PrinterJob ..................................................................... 5-8
The Printable and Pageable Interfaces ................................... 5-10
Overview ..................................................................................5-10
Example of Using Pageable and Book................................5-11
The PageFormat Class ................................................................... 5-12
Exercise: Using JDK 1.2 Printing................................................... 5-13
Preparation...............................................................................5-13
Tasks .........................................................................................5-13
Exercise Summary...................................................................5-14
Check Your Progress ...................................................................... 5-15
Think Beyond .................................................................................. 5-16
iii
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
v
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
viii
Preparation.............................................................................15-24
Tasks .......................................................................................15-24
Exercise Summary.................................................................15-25
Check Your Progress .................................................................... 15-26
Think Beyond ................................................................................ 15-27
Using the GridBagLayout ......................................................................16-1
Relevance.......................................................................................... 16-2
Objectives ......................................................................................... 16-3
Layout Managers ............................................................................ 16-4
The GridBagLayout ....................................................................... 16-6
The GridBagConstraints Class................................................ 16-10
Designing With GridBagLayout................................................ 16-12
Design Steps...........................................................................16-12
Example ..................................................................................16-14
RELATIVE and REMAINDER .................................................... 16-24
Exercise: Using GridBagLayout................................................. 16-26
Preparation.............................................................................16-26
Tasks .......................................................................................16-26
Exercise Summary.................................................................16-27
Check Your Progress .................................................................... 16-28
Think Beyond ................................................................................ 16-29
Delegation Event Handling ....................................................................A-1
Relevance........................................................................................... A-2
Objectives .......................................................................................... A-3
JDK 1.1 Event Model ....................................................................... A-4
What is Event Handling? ................................................................ A-5
Overview ...................................................................................A-5
Listeners Must Be Registered .................................................A-6
Coding With Events......................................................................... A-7
Event Classes .................................................................................... A-8
Overview ...................................................................................A-8
Event Utility Methods .............................................................A-9
Check Your Progress ..................................................................... A-10
Printing ....................................................................................................... B-1
Relevance........................................................................................... B-2
Objectives .......................................................................................... B-3
AWT Printing ................................................................................... B-4
Overview ................................................................................... B-4
Example ..................................................................................... B-7
AWT Printing Limitations .............................................................. B-9
Check Your Progress ..................................................................... B-10
Adding Fonts to the Java Runtime ........................................................C-1
Relevance........................................................................................... C-2
Objectives .......................................................................................... C-3
ix
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
xi
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Course Overview
With the advent of Swing and its maturing into the core packages, Java
technology now has a fully featured universally available graphical
user interface (GUI) library. Additional features of the Java
Development Kit (JDK) core packages provide full support for
localization and internationalization of programs. This is particularly
important in the context of Internet distribution of applets.
Developers taking this class will gain the essential skills to create top
quality user interfaces using the features of core JDK, Abstract
Windowing Toolkit (AWT), JFC, and Swing, as well as skills needed
for printing and localization of a program.
xii
Course Map
Each module begins with a course map that enables you to see what
you have accomplished and where you are going in reference to the
course goal. A complete map of this course is shown below.
Swing Introduction
Introduction
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
xiii
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Module-by-Module Overview
Module 1 Introduction.
This module discusses the relationship between AWT, JFC, and
Swing and how you might make a choice among the various GUI
component kits that are available to you.
xiv
Module-by-Module Overview
xv
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Module-by-Module Overview
xvi
Module-by-Module Overview
xvii
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Course Objectives
Upon completion of this course, you should be able to:
Control the look and feel of a program, by installing a prewritten look and feel, and by using borders
Note The course does not discuss the detailed issues of creating a
new look and feel.
xviii
Course Objectives
xix
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
xx
Module
Skills Gained
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
xxi
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Day 1
A.M.
Introduction
A.M.
Swing Foundations
P.M.
P.M.
Day 2
A.M.
A.M.
P.M.
P.M.
Day 3
A.M.
A.M.
P.M.
P.M.
Day 4
Utility Panes
A.M.
Program Localization
P.M.
P.M.
Day 5
A.M.
P.M.
xxii
xxiii
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
xxiv
Can you make basic use of the AWT, including laying out GUIs
with flow, grid, and border layout managers; and using simple
components, including programming event responses?
Introductions
Now that you have been introduced to the course, introduce yourself
to each other and the instructor, addressing the items shown on the
above overhead.
xxv
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
xxvi
xxvii
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Icons
Additional resources Indicates additional reference materials are
available.
xxviii
xxix
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
xxx
Introduction
Course Map
This module discusses the relationships among AWT, JFC, Swing, and
competing libraries.
Swing Introduction
Introduction
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
1-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
1
Relevance
Discussion How do you go about choosing among competing
component libraries for a Java technology project? What types of
features are important to you and why? How much do you know
about the history of Swing and JFC? Do you know about the
delegation event model, introduced with JDK 1.1?
1-2
1
Objectives
Upon completion of this module, you should be able to:
Select appropriate components from the Swing set for any given
user interface (UI) requirement
Introduction
1-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Course Contents
This course discusses most of the commonly used features of the Java
Foundation Classes, including the Swing component set. However, it
does not cover the two-dimensional (2D) drawing APIs, nor will you
learn how to create your own look and feel.
In addition to elements of the JFC, you will learn about printing with
the newer mechanisms added at JDK 1.2.
1-4
What Is JFC?
The JFC, or Java Foundation Classes, is a term used to describe a
number of packages that are available as an addition to JDK 1.1 and
which became core APIs in JDK 1.2. As a result of this, some of the
boundaries between JFC and core JDK have become a little blurred,
but for the purposes of this class, JFC includes these features:
Introduction
1-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
1
What Is JFC?
1-6
What is Swing?
Swing is an enhanced GUI component set. However, it also has a
couple of unusual features. Using Swing, you can write a program that
adopts either the look and feel of the host platform (rather like AWT
did,) or that uses a common look and feel written especially for the
Java programming language, called Metal. In fact, you can create your
own look and feel from scratch, or by modifying an existing one and
plugging it in to your program, either hard coded or so that the user
or system administrator can select one at runtime.
Note Writing a look and feel is not covered in this course.
Introduction
1-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Printing
JDK 1.1 provides basic support of printing, although this is limited in
a number of ways. For example, it is very difficult to print at a
resolution other than 72 dots per inch (dpi), which produces relatively
grainy graphics when compared with current printer capabilities.
The printing features of JDK 1.1 are still available, but have been
augmented by a new set, in the package java.awt.print, that
provides greater control over the output, including permitting higher
resolution printing and supporting the concept of page layouts and
books.
1-8
Introduction
1-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
1
Why Not Use AWT?
In addition to a wide range of customization options for the supplied
components, the Swing set is (almost entirely) made up of lightweight
components.
A lightweight component is one that is drawn by Java technology code
(Java code), and is distinguished from a component that is
implemented using features of the host systems libraries (a native
peer). The lightweight component concept was introduced into AWT
with JDK 1.1 and makes it relatively easy to create entirely new
components. Furthermore, an existing lightweight component can be
modified readily by subclassing. The heavyweight core AWT
components are not so easy to modify. Hence Swing components may
readily be extended and or customized in appearance and behavior.
1-10
Introduction
1-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
1
What Should a Replacement for AWT Offer?
General Features (Continued)
1-12
1
What Should a Replacement for AWT Offer?
General Features (Continued)
Introduction
1-13
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
1-14
1
What Should a Replacement for AWT Offer?
Performance Features (Continued)
The library itself should be 100% Pure Java, if you want to have
your application certified as such.
Introduction
1-15
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
1
What Should a Replacement for AWT Offer?
Platform Independence Features (Continued)
1-16
Introduction
1-17
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
1
Exercise: Investigate Swing Component set
Exercise objective View and manipulate all the GUI components in
the Swing set.
Preparation
The JDK 1.2 release includes a useful demonstration program that
shows all the Swing components and enables you to experiment with
the look and feel of each of them.
Tasks
Under the main installation directory of your JDK there is a directory
called demo. Under that is a directory called jfc, and under that is a
directory called SwingSet. Make the SwingSet directory your current
directory and issue the command:
java SwingSet
After a moment you will see a loading window with a progress bar.
When the loading process has completed, you will see a window with
a banner on it and a tab selection panel above. Select each of the tabs
and ensure that you have seen all the components in the Swing set.
Experiment with the control options that are offered by most of the
pages. Consider how these components could be applied to your
work.
1-18
1
Exercise: Investigate Swing Component set
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
Experiences
Interpretations
Conclusions
Applications
Introduction
1-19
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
1
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
1-20
Select appropriate components from the Swing set for any given
UI requirement
1
Think Beyond
Given that Swing is largely backward compatible with AWT and the
delegation event model, do you think you could write code to use
some of these components already? What changes do you think you
might have to make to an existing AWT 1.1 program to use Swing
components instead?
Introduction
1-21
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
1-22
Swing Foundations
Course Map
This module introduces some of the essential aspects of the Swing set
and addresses the first issues that you must understand to succeed in
translating a GUI from the AWT to Swing.
Swing Introduction
Introduction
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
2-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
2
Relevance
Discussion What sort of components are you familiar with from
other GUI libraries?
Would you like to see any new components added to the basic AWT
set?
2-2
2
Objectives
Upon completion of this module, you should be able to:
Name the Swing components that are direct substitutes for the
AWT components and modify an AWT user interface to use these
Swing components
Understand the multiple panes of the JFrame, and write code that
correctly uses the content pane for holding other components
Swing Foundations
2-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
2-4
2
Comparing Swing and AWT Components
Selecting Swing or AWT
Although the Swing components do work fairly well when used
alongside AWT components, complications can arise. Because of this,
it is generally best to ensure that a user interface uses exclusively
Swing components and does not mix Swing and AWT in the same
program.
Swing Foundations
2-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
2-6
Swing Foundations
2-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
2-8
Using a RootPaneContainer
Overview
A RootPaneContainer is actually a container for a number of other
panes; these are the root, glass, layered, and content panes. Most of the
time, you only need to be concerned with the content pane.
To perform most operations, such as setting a layout manager or
adding new components to the container as a whole, you need to refer
to the content pane. This is obtained from a RootPaneContainer
using the method getContentPane.
Content panes have a BorderLayout by default, so, to add a JButton
to a JFrame referred to by the variable myFrame, you would use code
of this form:
myFrame.getContentPane().add(myJButton, BorderLayout.NORTH);
Swing Foundations
2-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
2
Using a RootPaneContainer
The Root, Glass, and Layered Panes
The JRootPane forms the basis of a stack of several components. It
contains a GlassPane and a LayeredPane, and has a layout manager
that controls all the other panes and the menu if it is present.
The LayeredPane can contain a menubar, and also holds the allimportant ContentPane.
A LayeredPane allows a specific stacking order to be enforced on the
components that it contains. This is used for pop-up menus, tool tips,
and similar elements.
The GlassPane is a transparent pane that is used to collect events.
2-10
JFrame Essentials
Background
Much of the time, when you use a RootPaneContainer, it will
actually be a JFrame. This class is the Swing replacement for a
java.awt.Frame, and is similar to that class.
Because the JFrame is a RootPaneContainer, you must take care to
refer to the content pane when adding components or setting a layout
manager.
Swing Foundations
2-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
2
JFrame Essentials
Reacting to the System Menu
In addition to being the most common top-level Swing container, the
JFrame has a useful enhancement over the original java.awt.Frame.
It has behavior attached to its system menu button. In AWT if you
wanted a window to close when the system menu was used, you had
to code this behavior from scratch using a listener. With a JFrame, you
have a choice of three reactions that can be set using the
setDefaultCloseOperation method. The options are:
DO_NOTHING_ON_CLOSE
HIDE_ON_CLOSE
DISPOSE_ON_CLOSE
2-12
2
Exercise: Converting an AWT GUI to Swing
Exercise objective Convert sample user interfaces from AWT to the
Swing component set.
Preparation
Read the file README in the labs directory for module 2.
Run the programs ConvertIF1, ConvertIF2, and ConvertIF3 in the
solutions directory for module 2. This will show you what the
completed labs should look like. (You might need to resize the
windows when they are first displayed.)
Tasks
Edit the files ConvertIF1.java, ConvertIF2.java, and
ConvertIF3.java. Change all the components to their Swing
equivalents and modify the code appropriately to make any other
necessary changes.
If you have difficulty, there are some hints in the file HINTS. Try not to
look at this file too soon.
Swing Foundations
2-13
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
2
Exercise: Converting an AWT GUI to Swing
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
2-14
Experiences
Interpretations
Conclusions
Applications
2
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
Name the Swing components that are direct substitutes for the
AWT components and modify an AWT user interface to use these
Swing components
Understand the multiple panes of the JFrame, and write code that
correctly uses the content pane for holding other components
Swing Foundations
2-15
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
2
Think Beyond
Why do you suppose that the Swing top-level containers need a glass
pane to catch events?
Can you guess what consequence might arise if you add an AWT
(non-lightweight) component to a Swing container that has non-Swing
components in a stacking order on the layered pane?
2-16
Course Map
This module introduces some fundamental Swing components,
including Icons and Buttons.
Swing Introduction
Introduction
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
3-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
3
Relevance
Discussion The Swing set contains many components; how many of
these do you think you would be able to program with now?
Are there any features of Swing that are not present in AWT that you
might want to use?
3-2
3
Objectives
Upon completion of this module, you should be able to:
JLabel
JButton
JCheckBox
JRadioButton
ToolTips
JComboBox
JMenu
3-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
3-4
3-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
3
The Icon Interface
Implementing the Icon Interface
This example shows how you can implement the Icon interface
directly.
1 import javax.swing.*;
2 import java.awt.*;
3
4 public class TargetIcon implements Icon {
5
6
public void paintIcon(Component c, Graphics g, int x, int y) {
7
Color old = g.getColor();
8
g.setColor(Color.red);
9
g.fillOval(0, 0, 16, 16);
10
g.setColor(Color.white);
11
g.fillOval(3, 3, 10, 10);
12
g.setColor(Color.red);
13
g.fillOval(6, 6, 4, 4);
14
g.setColor(old);
15 }
16
17 public int getIconWidth() { return 16; }
18 public int getIconHeight() { return 16; }
19 }
3-6
3-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
3
The JLabel Class
JLabel Example
1 import java.awt.*;
2 import javax.swing.*;
3
4 public class IconTest extends JPanel {
5
6
public IconTest() {
7
TargetIcon target = new TargetIcon();
8
9
setLayout(new GridLayout(4, 1));
10
add(new JLabel("This is a normal label"));
11
add(new JLabel("This label has an icon", target,
12
SwingConstants.LEFT));
13
add(new JLabel("The next label has only an icon:"));
14
add(new JLabel(target));
15 }
16
17 public static void main(String args[]) {
18
IconTest it = new IconTest();
19
JFrame jf = new JFrame("Icon on a JLabel");
20
jf.getContentPane().add(it, BorderLayout.CENTER);
21
jf.setVisible(true);
22 }
23 }
This example produces labels showing text and or images. The images
are generated using the TargetIcon class from the previous section.
3-8
Tooltips
Swing components support tooltips. Tooltips are short help messages
that are displayed when the mouse cursor pauses over a component.
JLabel tipLabel = new JLabel("This label has a tooltip");
tipLabel.setToolTipText("This is a tooltip");
add(tipLabel);
3-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Buttons
The Swing package provides versions of all the AWT buttons. Like
other Swing components, Swing buttons can display graphics as well
as text.
You create a basic push button in Swing using the JButton class.
3-10
3-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
3
The JButton Class
Overview (Continued)
If you create a JButton with text, the label text is used by default as
the action command string. However, if you create a graphics-only
button or if the default action command string (which is the text label
of the button) is not what you need, you can define the action
command explicitly using the setActionCommand method.
JButton Example
1 import java.awt.event.*;
2
3 public class CutCopyPaste implements ActionListener {
4
5
public static final String CUT = "CUT";
6
public static final String COPY = "COPY";
7
public static final String PASTE = "PASTE";
8
String testMode;
9
10 public CutCopyPaste(String name) {
11
testMode = name;
12 }
13
14 public void actionPerformed(ActionEvent ae) {
15
if (testMode != null) {
16
if (ae.getActionCommand() == CUT) {
17
System.out.println("Cut from " + testMode);
18
}
19
else if (ae.getActionCommand() == COPY) {
20
System.out.println("Copy from " + testMode);
21
}
22
else if (ae.getActionCommand() == PASTE) {
23
System.out.println("Paste from " + testMode);
24
}
25
}
26 }
27 }
This code defines action command strings CUT, COPY, and
PASTE, used as the labels of the buttons themselves. It also defines
the action listener to be used by the buttons. When invoked, the
actionPerformed method describes which button was clicked.
3-12
3
The JButton Class
JButton Example (Continued)
1 Icon cutIcon = new ImageIcon("cut32x32.gif");
2 Icon copyIcon = new ImageIcon("copy32x32.gif");
3 Icon pasteIcon = new ImageIcon("paste32x32.gif");
4 add(cutButton = new JButton(cutIcon));
5 add(copyButton = new JButton(copyIcon));
6 add(pasteButton = new JButton(pasteIcon));
7 CutCopyPaste ccp = new CutCopyPaste("JButton Demo");
8
9 cutButton.setActionCommand(CutCopyPaste.CUT);
10 copyButton.setActionCommand(CutCopyPaste.COPY);
11 pasteButton.setActionCommand(CutCopyPaste.PASTE);
12
13 cutButton.addActionListener(ccp);
14 copyButton.addActionListener(ccp);
15 pasteButton.addActionListener(ccp);
This example demonstrates how the buttons can be created, and how
the action command can be set explicitly, even though the buttons do
not have any text.
3-13
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
3-14
3
The JCheckBox Class
JCheckBox Example
This code example shows how to use a JCheckBox in its simplest
form:
1 import javax.swing.*;
2 import java.awt.*;
3
4 public class CBox extends JPanel {
5
JCheckBox tb1, tb2, tb3;
6
7
public CBox() {
8
setLayout(new GridLayout(3,1));
9
add(tb1 = new JCheckBox("Left Channel"));
10
add(tb2 = new JCheckBox("Right Channel"));
11
add(tb3 = new JCheckBox("Bass Boost"));
12 }
13
14 public static void main(String args[]) {
15
JFrame jf = new JFrame("Checkbox Test");
16
jf.getContentPane().add(new CBox());
17
jf.pack();
18
jf.setVisible(true);
19 }
20 }
When run, this example produces a window like this.
3-15
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
3-16
3
The JRadioButton Class
JRadioButton Example
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4
5 public class RadioTest extends JPanel
6
implements ItemListener {
7
8
private JRadioButton tb1, tb2, tb3;
9
private ButtonGroup bg;
10
11 public RadioTest() {
12
setLayout(new GridLayout(4,1));
13
add(new JLabel("Select the audio output device:"));
14
add(tb1 = new JRadioButton("External Speakers"));
15
add(tb2 = new JRadioButton("Internal Speaker"));
16
add(tb3 = new JRadioButton("Headphones"));
17
18
tb1.addItemListener(this);
19
tb2.addItemListener(this);
20
tb3.addItemListener(this);
21
22
// make it behave like a radio interface
23
bg = new ButtonGroup();
24
bg.add(tb1);
25
bg.add(tb2);
26
bg.add(tb3);
27 }
28
29 public void itemStateChanged(ItemEvent ie) {
30
JRadioButton jtb = (JRadioButton)ie.getItem();
31
// have to check, since "unselecting" also
32
// generates an event
33
if (ie.getStateChange() == ItemEvent.SELECTED) {
34
System.out.println("Current output device is: " +
35
jtb.getText());
36
}
37 }
38
3-17
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
3
The JRadioButton Class
JRadioButton Example (Continued)
39
public static void main(String args[]) {
40
JFrame jf = new JFrame("RadioTest");
41
RadioTest it = new RadioTest();
42
jf.getContentPane().add(it, BorderLayout.CENTER);
43
jf.pack();
44
jf.setVisible(true);
45 }
46 }
47
This example produces output that looks like this:
3-18
3-19
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
3
The JComboBox Class
JComboBox Example
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4
5 public class ComboTest extends JPanel implements ItemListener {
6
7
private JComboBox jcb;
8
private String options[] = { "External Speakers",
9
"Internal Speaker", "Headphones" };
10
11 public ComboTest() {
12
TargetIcon target = new TargetIcon();
13
14
setLayout(new GridLayout(2,1));
15
add(new JLabel("Select the audio output device:"));
16
add(jcb = new JComboBox(options));
17
jcb.setEditable(true);
18
jcb.addItemListener(this);
19 }
20
21 public void itemStateChanged(ItemEvent ie) {
22
System.out.println("Item is: " + ie.getItem());
23
System.out.println("Selectable is: "
24
+ ie.getItemSelectable());
25 }
26
27 public static void main(String args[]) {
28
JFrame jf = new JFrame("Combo Test");
29
ComboTest it = new ComboTest();
30
jf.getContentPane().add(it, BorderLayout.CENTER);
31
jf.pack();
32
jf.setVisible(true);
33 }
34 }
3-20
3
The JComboBox Class
JComboBox Example (Continued)
This example creates a display that looks like this:
3-21
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
3-22
3
The JMenu Class
JMenu Example
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4
5 public class MenuTest extends JPanel
6
implements ActionListener {
7
8
public MenuTest() {
9
setLayout(new BorderLayout());
10
Icon cutIcon = new ImageIcon("cut.gif");
11
Icon copyIcon = new ImageIcon("copy.gif");
12
Icon pasteIcon = new ImageIcon("paste.gif");
13
14
JMenuBar jmb = new JMenuBar();
15
JMenu editMenu = new JMenu("Edit");
16
JMenuItem cutItem = new JMenuItem("Cut", cutIcon);
17
editMenu.add(cutItem);
18
cutItem.addActionListener(this);
19
20
JMenuItem copyItem = new JMenuItem("Copy", copyIcon);
21
editMenu.add(copyItem);
22
copyItem.addActionListener(this);
23
24
JMenuItem pasteItem = new JMenuItem("Paste", pasteIcon);
25
editMenu.add(pasteItem);
26
pasteItem.addActionListener(this);
27
28
jmb.add(editMenu);
29
add(jmb, BorderLayout.NORTH);
30
31
add(new JLabel("Look at the Edit menu above"),
32
BorderLayout.CENTER);
33 }
34
35 public void actionPerformed(ActionEvent ev) {
36
Object o = ev.getSource();
37
if (o instanceof AbstractButton) {
38
String command = ((AbstractButton)o).getActionCommand();
3-23
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
3
The JMenu Class
JMenu Example (Continued)
39 System.out.println("Action " + command + " occurred");
40
}
41
else {
42
System.out.println("Unrecognized action source");
43
}
44 }
45
46 public static void main(String args[]) {
47
JFrame jf = new JFrame("Menu Test");
48
MenuTest mt = new MenuTest();
49
jf.getContentPane().add(mt, BorderLayout.CENTER);
50
jf.pack();
51
jf.setVisible(true);
52 }
53 }
This example code produces output like this:
3-24
3-25
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
3
Additional Features of JMenu
Keyboard Accelerators (Continued)
The previous code produces the following example.
Menu Positioning
You can place menu bars anywhere in your application. This is a
significant change from the menu behavior in AWT. Since the
JMenuBar class is an extension of JComponent, you can position a
JMenuBar anywhere you would add things like buttons or labels; they
are no longer restricted to the physical frames of your application. Be
aware that positioning menu bars at locations other than the top of a
window might confuse users of your application.
3-26
3
Exercise: Using Basic Swing Components
Exercise objective Experiment with JComboBox, ToolTip, JLabel,
JRadioButton, and ButtonGroup.
Preparation
Read the file README in the labs directory for module 3.
Run the program Translate in the solutions directory for module 3.
This will show you what the completed lab should look like. (You
might need to resize the window when it is first displayed.)
Tasks
Two source files are in the labs directory for module 3. Edit the one
called Translate.java. At each point where you find a line
beginning:
//****
write the code necessary to implement the comment at that point.
Take care to use the variables that are already declared and in use by
the template.
3-27
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
3
Exercise: Using Basic Swing Components
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
3-28
Experiences
Interpretations
Conclusions
Applications
3
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
JLabel
JButton
JCheckBox
JRadioButton
ToolTips
JComboBox
JMenu
3-29
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
3
Think Beyond
What other components in the Swing set do you think you could use
now?
3-30
Course Map
This module discusses accessibility, Actions, and Keystrokes, which
provide ways to program required behavior in response to user input.
Swing Introduction
Introduction
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
4-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
4
Relevance
Discussion How do you, as a user, control a program? How would
you manage if you were unable to use a mouse or keyboard, or if you
were not able to see a screen? What would be involved in writing a
program that can be controlled by voice, or can send its output to a
Braille terminal?
As a programmer, how do you handle keyboard input that is intended
to control a program? Is this handling likely to be common among
multiple applications?
4-2
4
Objectives
Upon completion of this module, you should be able to:
4-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
JComponent Accessibility
Comprehensive accessibility services are defined for the Java
programming language through a number of interfaces. If you create
your own components from scratch, you must implement these
interfaces for your component if full accessibility is required. However,
for all the Swing components, this work has already been done. All
that remains to produce a functional accessible application is for you
to provide names and descriptions for the components in your user
interface.
The JComponent class defines a method getAccessibleContext
that returns an instance of the AccessibleContext (abstract) class.
Different component classes return different subclasses of
AccessibleContext according to their needs, but all of these
subclasses share two particular methods, which are
4-4
setAccessibleName(String)
setAccessibleDescription(String)
4
JComponent Accessibility
The first of these methods is used to provide a handle on the
particular component so that if, for example, a menu is named file
menu a user can say select file menu and the accessibility system
will react appropriately.
Although using these two methods is simple, it is important to ensure
that the name and description strings you provide are properly
localized, or that they can be localized from an external file. This issue
is discussed in depth in Module 13, Program Localization.
Many governments, notably the U.S. government, require that
software purchased for use in their own departments support assistive
technologies. Clearly, equal opportunity laws of this kind will place
non-accessible software at a significant disadvantage in the
marketplace, and it is worth remembering to make the small effort of
naming and describing your components when using Swing.
4-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Actions
An Action is a convenient encapsulation of a capability in a
component or program. javax.swing.Action is an interface that
extends ActionListener. As such, it has an actionPerformed
method, which can be invoked directly to run the action.
Although Action objects in Swing generally are often associated with
GUI components, it is important to realize that an Action can describe
a command to any kind of object, not just GUI objects.
As well as representing program behavior through the
actionPerformed method, the Action is designed to be attached to
user interface components directly. The JMenu and JToolBar classes
both have an add(Action) method that allows actions to be added
directly to them. JMenu also has a method insert(Action, int),
which enables you to put an Action into a menu at a specific position,
not just at the end.
4-6
4
Actions
To support the visual representation of actions, they carry both a
textual description and an icon which are used directly in a menu or
toolbar. Further, an Action can be enabled or disabled, and if a change
in its state occurs, the Action can issue events to notify a
PropertyChangeListener about this. Both JMenu and JToolBar
listen for these events and will grey out the Action if it is disabled.
If you use toolbars, it is important to restrict the number of items that
are added. This is partly for aesthetic reasons, and partly because the
toolbar will grow longer as more items are added. If it extends beyond
the width of the screen, it will be very difficult to use. If necessary, you
can create multiple toolbars, in which case they should be grouped
according to broad functional areas.
4-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Keystrokes
The javax.swing.KeyStroke class is used to represent keyboard
input from the user. To save memory, KeyStroke instances are shared,
which means that a factory method must be used to access them.
These factory methods are static methods called getKeystroke in
the Keystroke class. Different overloaded versions of the
getKeystroke method accept character codes (Unicode) or key
(scan) codes, modifiers (shift and so forth), key press, or key release to
be used to describe the desired keyboard activity.
4-8
4-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
4
Attaching an Action to a KeyStroke
WHEN_FOCUSED
WHEN_IN_FOCUSED_WINDOW
WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
4-10
4
Exercise 1: Investigate Action Objects
Exercise objective Use predefined Action objects.
Preparation
Read the file README.1 in the labs directory for module 4.
Run the program Actions in the solutions directory for module 4.
This will show you what the completed lab should look like. (You
might need to resize the window when it is first displayed.)
Tasks
The file Actions.java contains a template for this exercise. At each
point where you find a line beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
Extract the list of Action objects from the JTextPane and add
them to the menu and tool bar
4-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
4
Exercise 2: Investigate Keystroke Handling
Exercise objective Attach Action objects to keystrokes.
Preparation
Read the file README.2 in the labs directory for module 4.
Run the program Keystroke in the solutions directory for module 4.
This will show you what the completed lab should look like. (You
might need to resize the window when it is first displayed.)
Tasks
Edit the file Keystroke.java that contains a template for this exercise.
At each point where you find a line beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
4-12
Obtain the name of each of the Action objects that the JTextPane
provides
4
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
Experiences
Interpretations
Conclusions
Applications
4-13
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
4
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
4-14
4
Think Beyond
What types of accessibility interfaces might your programs be used
with?
How do actions and keystrokes facilitate reuse of components?
4-15
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
4-16
This module discusses the printing features of JDK 1.2, which provide
high-quality printed output.
Swing Introduction
Introduction
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
5-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
5
Relevance
Discussion What proportion of your programs require the ability to
create hard copy output? What features are important when creating
printed output?
5-2
5
Objectives
Upon completion of this module, you should be able to:
5-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
5-4
5-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
5
Implementing the Printable Interface
1 public class PrintableTextPane extends JTextPane
2
implements Printable {
3
4
public int print(Graphics g, PageFormat form, int page) {
5
if (page == 0) {
6
if (g instanceof Graphics2D) {
7
AffineTransform tr = new AffineTransform(form.getMatrix());
8
tr.translate(form.getImageableX(), form.getImageableY());
9
((Graphics2D)g).transform(tr);
10
}
11
super.paint(g);
12
return PAGE_EXISTS;
13
}
14
else {
15
return NO_SUCH_PAGE;
16
}
17
}
18 }
The Printable interface requires a single method:
int print(Graphics g, PageFormat f, int p)
This method must render the image of the printable onto the supplied
Graphics object. To support this, a PageFormat object is provided that
describes the current page size, margins and so forth. Additionally, the
page indexzero based, within this Printableis supplied.
If the page number indicates a page beyond the range for this
Printable, then the method should return the constant value
NO_SUCH_PAGE. Otherwise, PAGE_EXISTS should be returned. These
constants are defined in the Printable interface. The page index
provided is zero based, and relates to the pages in this Printable, not
the overall page number in the output document as a whole.
To align the drawing with the margins of the page, a transformation is
applied to the Graphics2D object. This is performed using an instance
of the AffineTransform class. The AffineTransform object is
constructed to perform translation by the amounts specified in the
PageFormat by the methods getImageableX and getImageableY.
5-6
5
Implementing the Printable Interface
The method getMatrix in the PageFormat object supplies the
transformation matrix that is appropriate to the required orientation of
the page.
Once the appropriate transformations have been applied to the
Graphics, the output is created. In this example, output is created in
the paint method of the parent JTextPane, but this can also be
achieved using any of the methods of the Graphics class.
5-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
5
Using the PrinterJob
1 PrinterJob pj = PrinterJob.getPrinterJob();
2 if (pj.printDialog()) {
3
PageFormat pf = pj.defaultPage();
4
pf = pj.pageDialog(pf);
5
6
pj.setPrintable(ta);
7
8
try {
9
pj.print();
10
System.out.println("Print completed");
11
}
12
catch (PrinterException e) {
13
e.printStackTrace(System.err);
14
System.out.println("Print failed");
15
}
16 }
17 else {
18
System.out.println("Print cancelled");
19 }
Before you can print output, you must create and configure a
PrinterJob object.
You can obtain a PrinterJob object simply by using the static method
getPrinterJob in the PrinterJob class. Next, you supply a
Printable object to describe the required output.
To set up the PrinterJob, the printDialog method presents you with
a dialog box that enables you to select the destination printer along
with other configuration such as the number of copies, and the banner
page title for the job.
If you click the Cancel button in this dialog box, then the
printDialog method returns false; otherwise, it returns true.
A page configuration dialog is launched by the pageDialog method.
This enables you to select page size, orientation, and margins.
You can configure the PrintJob to work on a Printable by calling
the setPrintable method.
5-8
5
Using the PrinterJob
When the PrinterJob has been set up and provided with something
to print, you invoke the actual printing process by calling the print
method of that PrinterJob.
Printing is performed in several passes; each pass collects a small strip
of the output from the print method of the Printable. Each call has
a different clip rectangle set, thus building up the whole page.
5-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
5-10
5
Printable and Pageable Interfaces
Overview (Continued)
A Pageable is a collection of Printable objects. Each Printable
typically represents a page (but may represent a group of pages), and
the Pageable can specify a different page layout for each Printable.
The easiest way to provide a Pageable is to use the Book class, which
implements the Pageable interface, and enables you to append pages
(each is actually described by a Printable object) to it.
5-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
5-12
5
Exercise: Using JDK 1.2 Printing
Exercise objective Experiment with the JDK 1.2 printing features.
Preparation
Read the file README in the labs directory for module 5.
Run the program PrintOut in the solutions directory for module 5.
When you are asked to choose a printer, select the print to file option if
possible and view the output using a graphics viewing program. This
will show you the required output from your solution.
Tasks
Edit the file PrintOut.java that contains a template for this exercise.
At each point where you find a line beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
Obtain a PrinterJob
5-13
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
5
Exercise: Using JDK 1.2 Printing
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
5-14
Experiences
Interpretations
Conclusions
Applications
5
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
5-15
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
5
Think Beyond
What kinds of transformations might you achieve using the
AffineTransform class?
What effects might be achieved by applying such transformations to
screen graphics?
5-16
Course Map
This module introduces the models, views, and controllers paradigm
that is fundamental to many of the more complex Swing components.
Swing Introduction
Introduction
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
6-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
6
Relevance
Discussion If you build a computational model of something, and
put a user interface onto that model, what issues arise when you need
to make changes, such as adding another presentational view,
modifying the way the model behaves, or adding new ways to interact
with the model?
6-2
6
Objectives
Upon completion of this module, you should be able to:
6-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
MVC Overview
The basis of MVC is that there are three distinct parts that make up
most screen presentations. These are a mathematical model of some
behavior (the model), a visual representation (the view), and a way for
the user to interact with the model and view (the controller).
The models, views, and controllers design pattern has been popular in
object-oriented software development for many years. It is particularly,
although not exclusively, applicable to user interface components, and
we will discuss it in that context.
6-4
6
MVC Overview
Model
New openness
notification
View
Controller
open
close
setOpenProportion
Open
Close
Figure 6-1
6-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
6
MVC Overview
Model
New openness
notification
View
Interface methods to
physical valve
Controller
Physical valve
open
close
setOpenProportion
Open
Close
Figure 6-2
6-6
6
MVC Overview
Model
New openness
notification
View/Controller
Figure 6-3
Combined View/Controller
Often, the visual representation and the controller GUI are the same
thing; it can be difficult or inappropriate in many MVC components to
distinguish clearly between these aspects.
In this example valve component, the controller might be
implemented as a push button, so that each time the button is clicked,
the state of the valve is toggled. For an analog valve (one that can be
partially opened,) the controller might be a slider or rotary dial of
some kind that both sets and displays the open proportion of the valve
model.
6-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Benefits of MVC
It might not be immediately obvious why the MVC model is better
than other ways of building GUI components. MVC is just an example
of good OO abstraction: building separate objects with good
encapsulation boundaries based on simple, self-contained
responsibilities, and clearly defined interfaces.
The representation of something to the user is logically a separate
problem from how it is represented in the computer. It is often
desirable to have multiple visual representations of the same model.
Also, it is often necessary to change the way a model is stored in the
computer, but such a change does not necessarily require any change
in the view or views.
Separating the model and view with clearly defined communication
between the two enables you, the programmer, to produce as many
different views as you need, without impacting the model. You can
also change the implementation of the model without impacting the
view classes.
The same logic applies to the separation of the controller.
6-8
6
Benefits of MVC
An interface is the ideal way to define the controller interface of the
model since it allows many different objects to act as models, simply
by implementing that interface. A similarly flexible mechanism is
needed for notifying the view of changes. You can use interfaces to do
this, but using AWT 1.1 style events is both a common and a
particularly effective way of implementing this interface.
You have seen that, in many GUI components, the view and controller
aspects share the same screen space. In such circumstances, it is
common to find a single class that represents both view and controller.
It is important that the model interact with the view and controller
aspects using the same techniques.
6-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
6-10
6
Implementing MVC in JDK 1.1
This is parallel to the delegation event mechanism, although the
definition of the Observable as a class in a single implementation
inheritance language is a little awkward in some situations.
Other custom mechanisms can be used to implement the model to
view notification if desired, although they are likely to share much
with either or both of the preceding mechanisms, so it is unlikely that
this would be a good approach in the general case.
Controller-to-model interfaces are usually created by defining an
interface that specifies one or more control methods and then having
the model implement that interface. This approach can be
implemented in any JDK revision.
6-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Event Sourcing
When you want to send events from a model, you must first decide
what class of event you want to send.
Generally, you should use an existing event class if one exists that
adequately describes the data you need to pass. If there is no predefined event class that is suitable, you might need to create a new
one. If you do this, it is best to start with an event that is reasonably
close to describing your data; ideally, one that can describe a useful
subset of your data by itself. Then subclass that event and add the new
fields and methods that you require.
The reason for reusing existing events is that it increases the chances of
your model and view being reusable in other code. For example, if you
create a model that fires an ActionEvent, it can be plugged directly
into a GUI that uses ActionEvent to trigger some behavior. If you had
created an entirely new event, you would have had to modify
(perhaps extensively) the existing code before it could interoperate
with your model.
6-12
6
Event Sourcing
If you do create a new event, you must also make a decision about the
type of listener that you will handle in your view classes. You could
require a listener for events of the parent class, or you could require a
listener that exactly matches your new event class. You could also do
both.
If you accept listeners of the parent event type, then you increase the
chances of reuse. Listeners of that type will not access all the
information about the event, but they might be able to operate usefully
with the limited information available from the parent event class. If
you do not accept parent type listeners, then existing event listeners
cannot be used at all.
If you accept only listeners of the parent type, then listeners that are
actually intended to receive the full information of your event must
use instanceof and a cast before they can access that data.
6-13
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Handling Listeners
When you have decided on your event and listener types, you must
decide how to distribute the events, and actually code the
add/removeXXXListener methods and a means of firing the events.
The first choice is whether the event firing method should be unicast
or multicast. A unicast event source can send events only to a single
listener. This can be quite limiting, reducing the reusability of your
component. For this reason, unicast event sourcing should not be
considered without a compelling reason.
Note You cannot enforce program correctness by means of unicast
event dispatch. A multiplexing adaptor can be added as the single
listener, and then be used to dispatch the event to many recipients.
6-14
6
Handling Listeners
Assuming you decide to implement your events as multicast, you can
implement the add/removeXXXListener methods with simple code
like this:
Vector listeners;
public void addMyEventListener(MyEventListener l) {
listeners.addElement(l);
}
public void removeMyEventListener(MyEventListener l) {
listeners.removeElement(l);
}
6-15
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
6-16
6
Dispatching the Event
private void issueEvent(Info i) {
Event ev = new MyEvent(this, i);
Vector cl = (Vector)(listeners.clone());
Enumeration e = cl.elements();
while (e.hasMoreElements()) {
((MyEventListener)e.nextElement()).doMyEvent(ev);
}
}
6-17
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
MVC in Swing
While the 1.1 AWT supports the use of MVC, many of the Swing
components are actually built using it.
Some of the Swing components, such as JLabel and JProgressBar
which only output information but have no input mechanisms, are
essentially views in their own right. However, they do not respond
directly to the events issued from a model.
Other components constitute controllers, these would be input-only
devices such as simple push buttons (that do not represent state) and
menus.
Many Swing components are combined view/controllers, perhaps
including their own built-in models. Examples of these would be
JCheckBox, JScrollBar, and JSlider.
6-18
6
MVC in Swing
The more complex Swing components (JList, JTable, JTree, and
JTextPane) use the MVC approach quite overtly. For example, the
javax.swing.text.Document defines the interface of the model used
by the text editors (that is, a document.) These classes are discussed
individually in later modules.
6-19
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
6
Exercise: MVC Demonstration Using the 1.1 Event Model
Exercise objective Implement the MVC model using interfaces and
the 1.1 Event Delegation model.
Preparation
Read the file README in the labs directory for module 6.
Run the programs SimpleMVC and MultiMVC in the solutions
directory for module 6. These will show you what the completed labs
should look like. (You might need to resize the windows when first
displayed.)
Tasks
The files ButtonController.java, MultiMVC.java,
ProgressView.java, TextView.java, ValveModelImpl.java,
contain a templates for this exercise. At each point where you find a
line beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
6-20
6
Exercise: MVC Demonstration Using the 1.1 Event Model
Tasks (Continued)
6-21
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
6
Exercise: MVC Demonstration Using the 1.1 Event Model
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
6-22
Experiences
Interpretations
Conclusions
Applications
6
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
6-23
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
6
Think Beyond
What types of models would you need for components like lists, trees,
tables, and text editors?
Would you ever require different models for any of these components?
6-24
Course Map
This module discusses the approach to MVC that is used by most
Swing components, and looks particularly at the JList.
Swing Introduction
Introduction
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
7-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
7
Relevance
Discussion You have seen how to implement an MVC model in a
number of ways; do you know how the Swing components achieve
this?
Would there be any value in having a standardized model-tocontroller interface, and if so how do you think this could be done?
7-2
7
Objectives
Upon completion of this module, you should be able to:
Write code to use the JList class initialized with data in either a
Vector or an Object array
7-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
MVC In Swing
The JList, JComboBox, JTable, JTree, and JEditorPane classes
make extensive use of the MVC design pattern. The JTable, JTree,
and JEditor classes are discussed in dedicated modules later in this
course.
This module introduces the common aspects of the MVC model as
implemented in Swing, and discusses these aspects in the context of
the JList class.
The models for these Swing classes are defined in appropriately
named interfaces, such as ListModel and TreeModel. In some cases,
these interfaces are implemented by an abstract class, such as
AbstractListModel, and a concrete implementation is provided,
appropriately named (for example, DefaultListModel). Many
programming situations do not require a new model. Where one is
needed, you can subclass either the Abstract... or Default...
model classes, or you can implement the interface directly. The
approach you choose depends upon how much of the default behavior
is appropriate for you.
7-4
7
MVC in Swing
All these Swing classes have combined view/controllers, but the
controllable aspects of the model are still accessible separately. Hence
you can create other separate controllers (or views) that interact with
the models.
In addition to creating your own controllers or views, the Swing
components enable you to take over partial control of some elements
of the view without having to rewrite much code. To support this
capability, Swing provides a cell renderer. In the JList, JTable, and
JTree classes, each element in a list or table, and each node in a tree is
called a cell. By creating a simple component that displays one element
of the overall data and installing it as the cell renderer, you can
customize much of the view of these components.
7-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Using a JList
One of the most immediately obvious differences between the JList
and the java.awt.List is that the JList does not provide
scrollbars automatically. To resolve this, you can place a JList in a
JScrollPane whenever the list might exceed the available display
area (which is almost always, given that the top level window might
be resized).
The JList class is simple to use in simple circumstances, and can
create its own ListModel if needed. To do this, you need only put the
data items into either a Vector or an array of Object and invoke the
JList constructor using the data as an argument.
This method might seem to embed the data and model inside the
JList, spoiling the MVC design pattern. This is not the case. In fact,
when created in this way, the JList constructs and initializes an
instance of DefaultListModel, and the accessor method getModel
allows you to retrieve the created model for subsequent manipulation
if you wish.
7-6
Using a ListModel
The methods defined in the ListModel interface are:
void addListDataListener(ListDataListener)
void removeListDataListener(ListDataListener)
Object getElementAt(int)
int getSize()
These methods allow access to the data, and can be used to register
listeners that will be notified when the data in the model changes.
However, there are no controller methods provided; that is, no
methods are provided that allow modification of the data.
The AbstractListModel implements the addXXXListener and
removeXXXListener methods, since the handling of event dispatch is
mundane and likely to be identical across any implementation of any
model. To support this, the AbstractListModel also provides a
number of fireXXX convenience methods. When called, these
construct and dispatch an appropriate ListDataEvent object to all
the registered listeners.
7-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
7
Using a ListModel
The DefaultListModel extends the AbstractListModel, providing a
real implementation of a list model, and also providing controller
methods to enable the data in the list to be manipulated. These
methods mimic the methods of java.util.Vector.
7-8
7
Exercise 1: Sharing a Model With MVC
Exercise objective Demonstrate the MVC model in Swing by
creating two JLists that share a data model.
Preparation
Read the file README.1 in the labs directory for module 7.
Run the program TwoLists in the solutions directory for module 7.
Observe that when an entry is added to either list, both are updated.
This will show you the required behavior for your solution.
Tasks
Edit the files TwoLists.java and ListController.java that contain
a template for this exercise. At each point where you find a line
beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
7-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
7
Exercise: Sharing a Model With MVC
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
7-10
Experiences
Interpretations
Conclusions
Applications
7-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Defining an Action
If you want to create your own actions you will need to implement the
Action interface. As so often is the case, there is an AbstractAction
class that implements most of the mundane work for you.
The methods of the Action interface are:
Object getValue(String key)
Object putValue(String key, Object value)
void setEnabled(boolean)
boolean isEnabled()
void addPropertyChangeListener(PropertyChangeListener)
void removePropertyChangeListener(PropertyChangeListener)
void actionPerformed(ActionEvent)
7-12
7
Defining an Action
The value methods enable you to set and retrieve four properties of
the Action. These are the name, long and short descriptions, and icon.
The key by which the property is specified is actually a String. The
Action class defines four constants that should be used for these
strings. These are:
Action.LONG_DESCRIPTION
Action.NAME
Action.SHORT_DESCRIPTION
Action.SMALL_ICON
Registered property change listeners will be notified (through the
propertyChange method) if the Action is enabled or disabled,
which is achieved by using the setEnabled(boolean) method.
The last method is the actionPerformed(ActionEvent) method,
which is called to invoke the actions behavior. It is the only method
not implemented by the AbstractAction class.
7-13
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
7
Action and Model Interactions
Controller
Model
Actions
(Inner classes in
Model, perhaps)
Model data
(private)
1) getActions
method returns an
array of Action
objects.
void actionPerformed
2) The Action
objects are added
to the controller.
3) Each Action has
access to the data in
the model and
implements a useful
actionPerformed
method operating
on that data.
int x
float y
Object z
Action [ ] getActions()
When you create Action objects, they need some way to perform the
action that they encapsulate. To do this they need to be able to change
the state of the model itself. This can be achieved in a number of ways.
One way is to define the Action classes as inner classes within the
model itself. This ensures that they have full access to the private
member variables of the model. Alternatively you can use package
(default) access on the members and define the Action classes in the
same package, or you can provide the Action objects with a reference
to the model instance, and implement the actionPerformed methods
in terms of the public methods of the model.
7-14
7
Exercise 2: Defining Action Classes
Exercise objective Implement the Action interface to create a
ListModel that provides Action objects.
Preparation
Read the file README.2 in the labs directory for module 7.
Run the program ListActions in the solutions directory for module
7. This will show you the required behavior for your solution.
Tasks
Edit the files ActionListController.java,
ActionListModel.java, and ListActions.java that contain a
template for this exercise. At each point where you find a line
beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
7-15
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
7
Exercise: Defining Action Classes
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
7-16
Experiences
Interpretations
Conclusions
Applications
7
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
Write code to use the JList class initialized with data in either a
Vector or an Object array
7-17
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
7
Think Beyond
Consider how the Action/KeyStroke mechanism can be used in a
variety of situations. What types of control is it less well suited to, and
how could you adapt it to those situations?
7-18
Course Map
This module looks at the JTable, and discusses ways to create data
models for it.
Swing Introduction
Introduction
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
8-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
8
Relevance
Discussion How often do you want to display or enter information
in a tabular form?
How would you achieve this using the standard AWT?
If you have a tabular component, what sort of control might be needed
over the source of the data? What control might be needed over the
presentation and editing of the data?
8-2
8
Objectives
Upon completion of this module, you should be able to:
8-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
JTable Fundamentals
JTable is one of the more complex Swing components, and the MVC
model is clearly evident in its design and use. The main interface that
defines its model is javax.swing.table.TableModel.
A JTable uses a model for columns as well as for the data itself. The
TableColumnModel keeps information about the number, names,
and order of columns, as well as information about their size, margins,
and selection modes.
The JTable should generally be presented in a JScrollPane. If this
is not done, the column headings will not be visible.
You can set a selection model using the method
setSelectionModel(ListSelectionModel) The selection model can
specify whether the selection is of a single cell, a single range of cells,
or multiple discontinuous ranges of cells.
8-4
8
JTable Fundamentals
To provide more control over the cell contents a JTable uses a
TableCellEditor to perform edits on a cell contents and a
TableCellRenderer to display the cell. Suitable editor and renderer
objects are provided by default for most situations, but these may be
replaced with customized versions if necessary.
8-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
8
Essential JTable Support Classes
JTable
TableColumnModel
(DefaultTableColumnModel)
TableModel
(AbstractTableModel,
DefaultTableModel)
TableColumn
TableCellRenderer
(DefaultTableCellRenderer)
Figure 8-1
TableCellEditor
(DefaultCellEditor)
Figure 8-1 shows the main classes used by the JTable. TableModel is
an interface that defines the interaction between the JTable and the
data it displays. AbstractTableModel and DefaultTableModel are
classes that implement this interface. As the name suggests, the
AbstractTableModel is an abstract class, while DefaultTableModel
is a concrete subclass of that.
In addition to modeling the data, the JTable uses the
TableColumnModel interface. This is normally used in the form of an
DefaultTableColumnModel object. A table column model describes
the size, order, headings and similar attributes of the individual
columns. To achieve this, the DefaultTableColumnModel class acts as
a collection of TableColumn objects, which describe these attributes for
individual columns.
8-6
8
Essential JTable Support Classes
The interfaces TableCellEditor and TableCellRenderer each
declare a single method. These methods have a return type of
Component and are used as factories for creating components that
actually perform the editing or rendering of cells in the table. Editors
and renderers can be specified as a default, associated with the table as
a whole, or associated with specific columns.
8-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
8-8
8
The TableModel Interface
8-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
8-10
Using a JTable
In many situations, the use of JTable is very simple. A variety of
constructors are provided, allowing you to create a table with no data
at all, no data but a specified size, or with data already in place.
If you want to specify data for the table cells, but do not need to
provide your own TableModel implementation, you can simply put
the table data into either a two-dimensional array, or a Vector of
vectors. Constructors are provided for the JTable that accept both
these forms, and a DefaultTableModel, initialized with your data,
will be created and installed behind the JTable for you.
If you need more control, you can use a constructor that accepts a
TableModel object, and perhaps specify the ListSelectionModel
and/or TableColumnModel that you need at the same time.
Constructing an instance of DefaultTableModel can be done in a
variety of ways, and both cell data and column heading names can be
supplied using vectors or arrays.
8-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Using an AbstractTableModel
If you need to create your own table model, you can implement the
TableModel interface directly, but in most cases you will subclass
either AbstractTableModel or DefaultTableModel.
If you want to control the way in which the table data is storedfor
example, if the storage is in a databaseand your table model acts as
the interface to that database, then you will probably start with the
AbstractTableModel. If you only want to make changes to
presentational aspects of the modelfor example, making one or more
cells non-editable, but you do not need to control the storage format of
the datathen you will probably simply extend
DefaultTableModel.
To create a concrete subclass of AbstractTableModel, you must
implement three methods. These are getRowCount,
getColumnCount, and getValueAt. These methods are reasonably
self-explanatory and simply provide access to the data of the model
itself.
8-12
8
Using an AbstractTableModel
Notice that the setValueAt method was not on the list of methods
that must be overridden. If you do not change it, the default form of
this method in the AbstractTableModel does nothing, effectively
making the model immutable.
If you want to create an editable table model using
AbstractTableModel as a basis, you need to override the
setValueAt method too. When a new value is set for a cell, the
setValueAt method implementation should call the convenience
method fireTableCellUpdated to ensure that notification is
passed to the listeners that a cell value has been changed.
8-13
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
8-14
Using a CellRenderer
A JTable has a default TableCellRenderer that is used for the
entire table unless an individual column has an overriding one. To
apply a new CellRenderer to a column, use the setCellRenderer
method of the TableColumn, which is itself obtained from the
TableColumnModel by the getColumn method.
A CellRenderer specified in this way is used for all cells in a
column, but different rows in the same column can exhibit different
appearance. When called, the renderer receives arguments specifying
what cell it is rendering, and hence can, if desirable, draw different
results accordingly.
8-15
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Writing a CellRenderer
The interface javax.swing.table.TableCellRenderer defines a
single method:
Component getTableCellRendererComponent(JTable t,
Object value, boolean isSelected, boolean hasFocus,
int row, int column)
When called, the method should return a fully configured Component
(such as a JLabel or JCanvas) that responds to paint method calls
appropriately, for the value given in the selection and focus state
specified, at the row and column specified. In other words, the
renderer object itself is actually a factory, and the name renderer is
somewhat misleading.
It is acceptable for the same component to be reused each time the
getTableCellRenderer method is called. This approach avoids
the need for many (possibly tens of thousands) of Component
instances to be waiting to be scrolled into view before becoming
useful.
8-16
Using a CellEditor
A CellEditor can be applied to a table, or column, using methods
that closely parallel the approach for a CellRenderer, that is the
JTable and TableColumn objects have setCellEditor methods.
The TableCellEditor interface is similar to the TableCellRenderer
interface, in that it defines a single method:
Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column)
This method is parallel to the getTableCellRendererComponent
method, although the boolean hasFocus argument is not present,
since the cell must have focus if it is being edited.
The DefaultCellEditor, which is a concrete implementation of the
TableCellEditor class, can be constructed so as to offer editing
with any of a JTextField, JCheckBox, or JComboBox . As such it is
sufficient to meet most requirements.
8-17
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
8
Exercise 1: Using JTable and TableModel
Exercise objective Become familiar with the use of JTable, and the
use of the TableModel getColumnClass method.
This is a series of four labs, essentially working on the same source
files. To allow you to start at any particular point in the sequence, and
to avoid jeopardizing your solution to one lab with the work for the
next, there are four labs directories and four solutions directories. The
files you will find in each form a logical progression of the same
classes.
Preparation
Read the file README in the labs.1 directory.
Run the program MyTable in the solutions.1 directory. Notice that
the second column is displayed and edited as a checkbox.
Tasks
Edit the files MyTable.java and MyTableModel.java in the labs.1
directory. These files contain the template for this exercise. At each
point where you find a line beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
8-18
8
Exercise 2: Controlling Editability With the TableModel
Exercise objective Become familiar with the use of the table model
to make particular cells of a table non-editable.
Preparation
Read the file README in the labs.2 directory.
Run the program MyTable in the solutions.2 directory. Notice that
the first and second columns are non-editable, while the third and
fourth columns may be edited.
Tasks
Edit the files MyTable.java and MyTableModel.java in the labs.2
directory. These files contain the template for this exercise. At each
point where you find a line beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
8-19
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
8
Exercise 3: Using a CellRenderer
Exercise objective Become familiar with the use of a CellRenderer
in a table.
Preparation
Read the file README in the labs.3 directory.
Run the program MyTable in the solutions.3 directory. Notice that
the third column is now presented as a colored block.
Tasks
Edit the files MyTable.java, MyTableModel.java, and
ColorRenderer.java in the labs.3 directory. These files contain the
template for this exercise. At each point where you find a line
beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
8-20
8
Exercise 4: Using a Cell Editor
Exercise objective Become familiar with the use of a cell editor in a
table.
Preparation
Read the file README in the labs.4 directory.
Run the program MyTable in the solutions.4 directory. Notice that
you can now edit the third column using a combo box that lists color
names.
Tasks
Edit the files MyTable.java, MyTableModel.java, and
ColorRenderer.java in the labs.4 directory. These files contain the
template for this exercise. At each point where you find a line
beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
8-21
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
8
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
8-22
Experiences
Interpretations
Conclusions
Applications
8
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
8-23
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
8
Think Beyond
In what other ways could you use a table? Might you be able to use it
as the basis of a spreadsheet? If so, how might you go about this?
8-24
This module discusses the use of JTree, and editors and renderers.
Swing Introduction
Introduction
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
9-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
9
Relevance
Discussion A tree component is valuable in a variety of situations, of
which at least one is obvious. How many can you think of?
9-2
9
Objectives
Upon completion of this module, you should be able to:
9-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
JTree Foundations
JTree makes extensive use of the MVC paradigm; the interface
javax.swing.tree.TreeModel defines the model.
Like the JTable, selections may be specified as either single cell, single
range, or multiple ranges. Constants that define these three
possibilities are defined in the class
javax.swing.tree.TreeSelectionModel.
Editors and renderers are used by the tree too, so two interfaces are
defined, TreeCellEditor and TreeCellRenderer. These are
applied to the entire tree.
To construct a JTree with simple data you need to provide a
TreeModel. Other constructors take either Hashtable or Vector
objects, but these provide insufficient control for most purposes.
9-4
9-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
9
The DefaultTreeModel and DefaultMutableTreeNode
Building a TreeModel (Continued)
Finally, you construct the DefaultTreeModel instance itself by
providing the root DefaultMutableTreeNode as the argument to the
constructor of the DefaultTreeModel.
Example
1 import java.awt.*;
2 import javax.swing.*;
3 import javax.swing.tree.*;
4
5 public class TreeTest {
6
private static Object [] nodeNames = { "one", "two", "three",
7
"four", "five", "six", "seven", new Integer(8),
8
new Integer(9), new Float(10) };
9
private static boolean [] leaf = { false, true, true, false,
10
true, true, false, true, true, true };
11
12 public static void main(String args[]) {
13
JFrame jf = new JFrame("Tree Test");
14
DefaultMutableTreeNode [] nodes = new DefaultMutableTreeNode[10];
15
for (int i = 0; i < nodes.length; i++) {
16
nodes[i] = new DefaultMutableTreeNode(nodeNames[i], !leaf[i]);
17
}
18
nodes[0].add(nodes[1]);
19
nodes[0].add(nodes[2]);
20
nodes[0].add(nodes[3]);
21
nodes[0].add(nodes[6]);
22
nodes[0].add(nodes[9]);
23
nodes[3].add(nodes[4]);
24
nodes[3].add(nodes[5]);
25
nodes[6].add(nodes[7]);
26
nodes[6].add(nodes[8]);
27
28
JTree jt = new JTree(nodes[0]);
29
jf.getContentPane().add(jt, BorderLayout.CENTER);
30
jf.pack();
31
jf.setVisible(true);
32 }
33 }
9-6
9
The DefaultTreeModel and DefaultMutableTreeNode
Example (Continued)
The example just listed produces this output.
Notice how the structure correlates to the way the nodes were created
and added to one another.
9-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
9-8
9
The TreeModel Interface
The method getIndexOfChild determines the position in the tree
of a particular node.
You can use the isLeaf method to determine if a particular node is a
leaf node or not. In some tree structures, the definition of a leaf node is
simply that it has no children, while in other structures (such as a file
system directory hierarchy) a leaf node is quite distinct from a nonleaf, even if the non-leaf has no children.
Use the method valueForPathChanged should be used to issue the
events that notify that a node has changed its value.
9-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
9-10
9
Exercise: Using JTree and DefaultTreeModel
Exercise objective Use DefaultMutableTreeNode to construct a
DefaultTreeModel, then use that tree model to construct a JTree.
Preparation
Read the file README in the labs directory for module 9.
Run the program CompTree in the solutions directory. Compare the
displayed tree with the GUI code in ALayout.java.
Tasks
Edit the file CompTree.java in the labs directory that contains a
template for this exercise. At each point where you find a line
beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
9-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
9
Exercise: Using JTree and DefaultTreeModel
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
9-12
Experiences
Interpretations
Conclusions
Applications
9
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
9-13
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
9
Think Beyond
Could you handle a tree that is of theoretically unlimited depth? Can
you conceive of such a situation arising?
9-14
10
Course Map
This module discusses the use of JTextPane and styles to provide
complex document editing capabilities.
Swing Introduction
Introduction
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
10-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
10
Relevance
Discussion Are the TextArea and TextField components of AWT
sufficient for all needs? If not, what additional features could be
useful?
10-2
10
Objectives
Upon completion of this module, you should be able to:
10-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
10
10-4
10
10-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
10
Using the JTextPane
JEditorPane, and hence JTextPane, are capable of interpreting
content. For example, they can read a hypertext markup language
(HTML) file, and have it rendered and edited in a what you see is
what you get (WYSIWYG) format. Content handling is provided for
HTML and rich text format (RTF) by default, and is extensible. Writing
your own content handler (known as the EditorKit) will be
examined in more detail in the next module.
The content type can be specified in two ways. The method
setContentType allows you to specify a MIME-type string directly,
while the method setURL allows you to specify a uniform resource
locator (URL) from which the editors contents will be loaded. The
content type will be obtained from the URL if possible. That is, for
HTTP:// URLs, if the server supplies content type information, then
this will be used by the editor.
10-6
10
10-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
10
Styles and JTextPane
StyleConstants also has convenience methods that enable you to
add an attribute to a MutableAttributeSet (such as a Style).
These methods are called setXxx where Xxx represents the attribute
name; for example, setBold, setItalic, and setUnderline. The methods
take two arguments. The first is the MutableAttributeSet to be
affected, and the second is dependent upon the attribute to be set. For
example setBold takes a boolean.
Once defined, a Style may be applied to either a whole paragraph, or
to a run of characters. If a different Style is applied to a whole
paragraph and to a run of characters in the same paragraph, then the
attributes that make up the Style applied to the character run will
take precedence over the attributes of the Style applied to the
paragraph as a whole. Where the paragraph style specifies an attribute
type that is not mentioned in the character run set, then the paragraph
attribute shows through.
The hierarchical nature of styles also allows an attribute from a parent
Style to show through into a child Style. For example, if a parent
style specifies Bold=true, FontSize=12, and another style is defined as
a child of that style specifying Underline=true, Bold=false, then the
final result of applying the second style is that the characters are 12
points, underlined, and not bold. This is illustrated in the following
table:
Table 10-1 Hierarchical Nature of Styles Example
10-8
Parent
Child
Result
Bold
Underline
FontSize
12
12
10
Constructing Styles
Before a Style can be used in a StyledDocument, it must be created
and configured to represent the desired attributes. Even before that, a
StyleContext must exist. The StyleContext is both a factory and
container for Style objects. Create a StyleContext simply using the
no-arguments constructor.
Style objects themselves are created in one or more hierarchies; in
this way, the attributes specified by a particular style might imply use
all attributes from all Style objects in this hierarchy, with the
attributes nearer to the root being overridden by those further down
the tree. Therefore, when you want to create a new Style, specify
the parent style, or null if the Style is to be a root stylethat is,
one with no parent.
After you have created the new Style object, you can set the
attributes for it using the StyleConstants convenience methods.
Each method takes the Style (the formal parameter is actually a
MutableAttributeSet, but recall that Style is a subclass of that)
and an argument of suitable type to qualify the attribute in question.
Hence setBold takes a boolean, and setFontSize takes an int.
10-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
10
Applying Styles
A Style may be applied to a whole paragraph, or to a range of
characters. One Style at a time may apply to a paragraph, but styles
applied to a character range can either replace all styles previously
applied to the range, or augment them. In either case, the Style of the
paragraph as a whole will show through where attributes are not
overridden by the character Style.
10-10
10
10-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
10
Images in JTextPane
You have seen how to insert Component objects into the text of a
JTextPane, and therefore you know that you can insert a Canvas or
JCanvas and use it to place an image into the display. In fact, the
JTextPane supports a lighter weight mechanism for including
pictures in text. This is achieved using Icon objects in a fashion very
similar to that used for displaying Component objects.
Icon is an interface that defines the methods getIconHeight
getIconWidth and paintIcon. The ImageIcon class provides a
convenient way to create an Icon from an Image, or a file or URL
containing a graphics interchange format (GIF) image or a similar
graphic.
Once you have created a Style and an Icon, use the
StyleConstants.setIcon method to apply the Icon to the Style.
Then use the setCharacterAttributes method (not the
setLogicalStyle method) to set the style on a space character the
same way as for displaying a Component.
10-12
10
Images in JTextPane
A shorthand technique for this mechanism is available in the
insertIcon method of the JTextPane class.
Note The content handlers being used by the JTextPane might reject
either components or icons.
10-13
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
10
Exercise: Using JTextPane and Styles
Exercise objective Become familiar with the use of JTextPane and
Styles.
Preparation
Read the file README in the labs directory for module 10.
Run the program Editor in the solutions directory. Create new styles
as both root and child styles by entering the name for the new style in
the text field at the top right of the Style editor window.
Experiment with applying these styles to paragraphs, and by mixing
and overriding onto character selections.
Create derived styles. Then modify aspects of the font definition,
deselect the Inherited checkbox, click the Apply button, and then
apply the style in various ways to your text.
Tasks
Edit the files Editor.java, FontPane.java, StylePane.java, and
StyleView.java that contain the template for this exercise. At each
point where you find a line beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
10-14
10
Exercise: Using JTextPane and Styles
Tasks (Continued)
10-15
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
10
Exercise: Using JTextPane and Styles
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
10-16
Experiences
Interpretations
Conclusions
Applications
10
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
10-17
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
10
Think Beyond
What is the role of a model in the text editing components you have
just studied?
What features do these models need?
Is one model sufficient for all text documents?
10-18
11
Course Map
This module discusses features of Swing related to programming in a
multi-threaded environment, and for controlling the appearance of
your GUIs.
Swing Introduction
Introduction
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
11-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
11
Relevance
Discussion Do you write multithreaded programs? Did you know
that Swing does not allow multithreaded operation?
Would you like more control over the appearance of your programs
when running them with Swing?
11-2
11
Objectives
Upon completion of this module, you will be able to:
11-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
11
11-4
11
Swing Is Not Thread Safe
11-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
11
11-6
11
Swing Is Not Thread Safe
Three methods in the basic JComponent class are thread safe in all
Swing components: repaint, revalidate, and invalidate. These
methods are thread safe because they are intended to be called by the
application program to trigger redisplay, or recalculation of display by
the AWT thread. As such, the methods themselves actually do not
perform any real work in the caller thread, but send a request to the
AWT thread to perform the required work when it is able.
The listener methods addXXXListener and removeXXXListener
are always thread safe, in that they do not affect the component in any
way. Note however that there are no guarantees about the exact
temporal relationship between adding a listener, and the first event
that the listener receives. That is, if an event is caused in a component
at approximately the same moment after a listener has called
addXXXListener, the event might not be reported to the listener.
Similarly an event can be delivered to a listener after the listener has
called removeXXXListener.
11-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
11
11-8
11
Calling Methods From Other Threads
11-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
11
11-10
11
Communicating Between Threads
Another support class, javax.swing.Timer, can be used to call the
actionPerformed method of one or more ActionListener objects
at intervals. When these calls occur, they are made by the AWT thread.
As before, the exact timing of the calls to the actionPerformed
method cannot be guaranteed. In fact, it is possible for the calls to be
delayed to the extent that one has not been executed before the
following one (or more) is due. The Timer class has an option that
permits the overrun ticks to be abandoned if preferred.
11-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
11
11-12
11
Using Borders
Applying a Border to a JComponent is very easy: The JComponent
class has a method setBorder(Border b). To use the method, you
simply need to obtain a Border that suits your needs. Rather than
construct a new Border for every component, it is more efficient to
reuse them. To this end, a factory class, BorderFactory, provides a
series of factory methods to construct each type of Border. If these
methods can reuse an existing Border, then they will do so, reducing
the memory demand of the Swing system, even in the face of extensive
Border use.
More than one Border may be used on a single component by means
of the CompoundBorder class. This simply combines two Border
objects, placing one inside the other and wrapping up the result as a
single Border. You can nest this approach as necessary to put many
borders around a single component.
The AWT components define a method setInsets. However, the
preferred way to place blank space around a Swing component is to
use the EmptyBorder instead.
11-13
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
11
Border Appearance
A variety of borders are provided by Swing. They are illustrated in
Figure 11-1.
Figure 11-1
11-14
11
11-15
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
11
11-16
UIManager.getCrossPlatformLookAndFeelClassName
UIManager.getSystemLookAndFeelClassName
11
Controlling Look and Feel
You can change the current look and feel at any time, including while
the program is running. However, it could be very disconcerting for
the user if the appearance of a program changed entirely without a
very obvious reason. The menu option that is used to trigger the
change should be well enough protected with messages asking Are
you sure? so that the change cannot happen by accident.
Swing permits you to create your own look and feel, either by
subclassing and modifying an existing one, or from scratch. However
this topic is beyond the scope of this course.
11-17
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
11
Focus Handling
Swing supports the use of an explicit focus manager, and installs one
of its own by default. The Swing focus manager requires the use of
JComponent methods, set/getNextFocusableComponent and
isManagingFocus, that do not exist in the AWT Component class.
If you need to use a mixture of Swing and AWT components in a GUI
(which is discouraged), you should disable the Swing focus manager,
since it will not work properly under such conditions. To disable it,
call the static method disableSwingFocusManager on the class
javax.swing.FocusManager.
If you need to install a new FocusManager, use the static method
setCurrentManager in the FocusManager class. You will see two
reasons why you might want to do this in the next section.
11-18
11
11-19
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
11
Focus Traversal
After the first component is focused using the decision-making
processes just outlined, the next question is how focus moves around
components in a GUI. If the mouse is used to move focus explicitly,
then this occurs entirely under user control; however, when using
keyboard navigation you might want to control where the focus goes
when Tab is pressed.
Normally, focus moves from left to right and top to bottom, in the
same way as words on an English page. The DefaultFocusManager
actually examines the x,y coordinates of each component to derive this
order.
If you want, you can specify that one component follows another in
focus order using the setNextFocusableComponent method of the
JComponent class.
In some situations, it might be more appropriate to replace the
DefaultFocusManager with a custom-written focus manager, in
which case you can code your own navigation according to any
criteria.
11-20
11
Focus Traversal
A JComponent can manage focus traversal within itself if desired. To
do this, you must subclass JComponent (or some other Swing
container,) enable keyboard events, and code the method
processKeyEvent to perform the required navigation. Finally, your
JComponent must return true from the method isManagingFocus
from the moment that it is given focus, until the time when focus
should leave that JComponent. This must be done because the
JComponent will pass keys to the FocusManager first, before
processing them itself, and it is important that the receiving
FocusManager should know that it must not get involved.
11-21
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
11
Exercise 1: Observe Default Focus Traversal
Exercise objective Observe the default focus behavior in Swing
layouts.
Tasks
Run the program Focus1 and notice how the focus is transferred from
left to right and top to bottom, in the same way as written English.
11-22
11
Exercise 2: Control Focus Traversal
Exercise objective Investigate the use of
setNextFocusableComponent to control tab focus order.
Preparation
Read the file README.2 in the labs directory for module 11.
Run the program Focus2 in the solutions directory and notice that
focus no longer progresses from left to right and top to bottom.
Tasks
Edit the file Focus2.java that contains a template for this exercise. At
each point where you find a line beginning:
//****
write the code necessary to implement the comment at that point.
The comment parts of the source will add or complete the following
behavior:
11-23
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
11
Exercise 3: Control Default Focus Position
Exercise objective Investigate the significance of component adding
order to the default focus position.
Preparation
Read the file README.3 in the labs directory for module 11.
Run the program Focus3 in the solutions directory for module 11,
and note the location of the focus when the window is first selected.
Do not use a mouse click in the body of the window to select the
whole window for focus, as this will disguise the default focus.
Tasks
Edit the file Focus3.java that contains the template for this exercise.
At each point where you find a line beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
11-24
11
Exercise 4: Install a Look and Feel
Exercise objective Control the look and feel of a running program.
Preparation
Read the file README.4 in the labs directory for module 11.
Run the program LnF in the solutions directory for module 11.
Select host look and feel and cross-platform look and feel using the
radio buttons.
Tasks
Edit the file LnF.java that contains the template for this exercise. At
each point where you find a line beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
Cause the Swing system to repaint entirely when a new look and
feel has been installed
11-25
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
11
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
11-26
Experiences
Interpretations
Conclusions
Applications
11
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
11-27
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
11
Think Beyond
What circumstances might warrant creating your own look and feel?
11-28
12
Utility Panes
Course Map
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
12-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
12
Relevance
Discussion Do your programs use file and directory browsing?
Do you need user interfaces that allow space to be divided under user
control between two or more regions of the same frame?
Do you need to present message dialogs to your users?
12-2
12
Objectives
Upon completion of this module, you should be able to:
Utility Panes
12-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
12
Utility Panes
A significant feature of Swing is the variety of high-level components
available for immediate use in an application. Swing includes several
useful containers. This module describes the following:
12-4
12
The JFileChooser
Description
One of the simplest additions you can make to an application to give it
a mature feel is using a graphical file system viewer anytime you need
to browse or choose files. The AWT package included the
FileDialog class which could be opened in Save or Load mode, but
was inflexible. The Swing package contains the JFileChooser.
Figure 12-1
Utility Panes
12-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
12
The JFileChooser
Example
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4
5 public class ChooserTest extends JPanel
6
implements ActionListener {
7
8
private JButton goButton;
9
private JLabel display;
10 private JFileChooser jfc = new JFileChooser();
11
12 public ChooserTest() {
13
goButton = new JButton(Pick File);
14
add(goButton);
15
display = new JLabel(Chosen file will be shown here);
16
add(display);
17
18
goButton.addActionListener(this);
19 }
20
21 public void actionPerformed(ActionEvent ae) {
22
int status = jfc.showOpenDialog(this);
23
if (status == 0) {
24
display.setText(You chose:
25
+ jfc.getSelectedFile().getName());
26
}
27
else {
28
display.setText(File chooser was cancelled);
29
}
30 }
31
32 public static void main(String args[]) {
33
JFrame jf = new JFrame(FileChooser test);
34
ChooserTest it = new ChooserTest();
35
jf.getContentPane().add(it, BorderLayout.CENTER);
36
jf.pack();
37
jf.setVisible(true);
38 }
39 }
12-6
12
The JFileChooser
Using the JFileChooser
The JFileChooser offers a number of useful features. In the example
shown the chooser is running in open mode; that is, it prompts the
user to select a file for opening. You can ask for the chooser to work in
save mode, which causes the buttons and title to be labelled
appropriately, by launching it with the showSaveDialog method
instead of the showOpenDialog method (see line 22 in the previous
example). For complete control over the appearance, you can use the
showDialog method, which enables you to specify the text that will be
displayed on the trigger button.
Utility Panes
12-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
12
The JFileChooser
You can apply filters to the JFileChooser too. You can ensure, for
example, that only files with the extension .gif are listed. Filters are
subclasses of the abstract class
javax.swing.filechooser.FileFilter. No filters are provided by
default, but you only need to implement two methods to create a filter.
These methods are:
12-8
12
The JTabbedPane
Description
Owing to its ease of navigation among categorized information, the
tabbed panel has made its way into just about every major computer
application. The JTabbedPane is the Swing answer to this useful
component. With it, you can create a segmented display with very
little effort.
Figure 12-2
Utility Panes
12-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
12
The JTabbedPane
Using the JTabbedPane
Creating a JTabbedPane is very straightforward:
jtp = new JTabbedPane();
//or
jtp = new JTabbedPane(int position);
These create empty tabbed panes. The default constructor puts tabs on
the top, but you can use the SwingConstants to put the tabs on the
top, left, bottom or right using the second version of the constructor.
After the pane is created, you will need to add the tabs. Each tab
contains a component. Since only a single component may be specified
when creating the tab, you normally specify a container. The addTab
method takes a text label and a Component reference.
jtp.addTab("System", systemPane);
12-10
12
The JTabbedPane
Using the JTabbedPane (Continued)
The addTab method simply appends a new tab to the current set of
tabs in the pane. If you need to locate a tab after it has been added,
you can search using the following methods:
indexOfComponent(Component comp)
indexOfTab(Icon icon)
indexOfTab(String title)
If you need a reference to the component within a tab, then you can
use the getComponentAt(int index) method.
You also have more direct control over where a tab goes if you need it.
You can use the insertTab method with the following syntax:
public void insertTab(String title, Icon icon,
Component component,
String tip, int index)
Utility Panes
12-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
12
The JTabbedPane
JTabbedPane Example
1 import java.awt.*;
2 import java.util.*;
3 import java.awt.event.*;
4 import javax.swing.*;
5
6 public class TabTest extends JPanel
7
implements ItemListener {
8
9
private JTabbedPane jtp;
10 private JCheckBox netCheckBox;
11 private JPanel systemPane = new JPanel();
12 private JPanel audioPane = new JPanel();
13 private JPanel internetPane = new JPanel();
14
15 public TabTest() {
16
setLayout(new BorderLayout());
17
jtp = new JTabbedPane();
18
19
netCheckBox = new JCheckBox(
20
"Internet Connection", true);
21
netCheckBox.addItemListener(this);
22
systemPane.add(netCheckBox);
23
24
audioPane.add(new JLabel("Audio configuration"));
25
internetPane.add(new JLabel("Internet configuration"));
26
27
jtp.addTab("System", systemPane);
28
jtp.addTab("Audio", audioPane);
29
jtp.addTab("Internet", internetPane);
30
31
add(jtp, BorderLayout.CENTER);
32 }
33
12-12
12
The JTabbedPane
JTabbedPane Example (Continued)
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 }
Utility Panes
12-13
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
12
The JSplitPane
Description
If you have interfaces that show multiple distinct areas for use at the
same time, then that interface might benefit from using a split pane.
The JSplitPane comes with two areas, either a top/bottom pair, or a
left/right pair. The main feature of the split pane is that the user can
manually adjust how much space is given to each component at
runtime. Here is an example of JSplitPane, showing the way the
center boundary can be moved.
Figure 12-3
12-14
12
The JSplitPane
JSplitPane Example
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4
5 public class SplitTest extends JPanel {
6
7
public SplitTest() {
8
JSplitPane sp = new JSplitPane(
9
JSplitPane.HORIZONTAL_SPLIT,
10
new JTextArea("This is one text area"),
11
new JTextArea("This is another text area"));
12
setLayout(new BorderLayout());
13
add(sp, BorderLayout.CENTER);
14 }
15
16 public static void main(String args[]) {
17
JFrame jf = new JFrame("SplitPane Test");
18
SplitTest st = new SplitTest();
19
jf.getContentPane().add(st, BorderLayout.CENTER);
20
jf.pack();
21
jf.setVisible(true);
22 }
23 }
Utility Panes
12-15
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
12
The JSplitPane
Controlling the Divider
An important behavior of the JSplitPane is that it respects the
minimum size of the components that it displays. This means that if
you are using the JSplitPane to display two large components, you
will need to call the setMinimumSize(Dimension) method of those
components; otherwise, you will find that the slider bar is immovable.
The divider of a JSplitPane has several properties which may be of
use to you in certain situations:
Table 1: JSplitPane Divider Properties
Property Name
get()
set()
Description
dividerLocation
The current position (in pixels relative to the upper-left corner of the
pane) of the divider
dividerSize
lastDividerLocation
(is)
continuousLayout
minimumDividerLocation
maximumDividerLocation
orientation
12-16
12
The JSplitPane
Controlling the Divider (Continued)
The behavior of the divider is largely dictated by the reported
preferred and minimum sizes of the two components in the pane. You
may need to manually set these properties for your components to get
the split pane divider to behave correctly.
Utility Panes
12-17
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
12
The JScrollPane
Description
The JScrollPane container enables you to display a component much
larger than the physical area you have to show it in. While the AWT
package includes a scrollable pane as well, the Swing version gives
you quite a bit more control.
The JScrollPane is made up of nine parts:
Row header
Corners
Viewport
Vertical scrollbar
Column header
Horizontal scrollbar
The viewport and the scrollbars are fairly obvious, but you can also
control the row and column headers and the four corners. The
viewport and headers are all JViewport objects, the scrollbars are
JScrollBar objects, and the four corners can be any Component you
want.
12-18
12
The JScrollPane
Assigning Components to Regions of a JScrollPane
To put specific components in each of the nine areas, you use code
similar to this:
1
2
3
4
5
6
7
Utility Panes
12-19
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
12
The JScrollPane
Controlling Scrolling
You can also specify what scrolling policies are used:
1 jsp.setVerticalScrollBarPolicy(
2
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
3 jsp.setHorizontalScrollBarPolicy(
4
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
12-20
12
The JOptionPane
Description
The JOptionPane class contains several static methods to display
common warning and error messages in a dialog box.
Figure 12-4
Utility Panes
12-21
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
12
The JOptionPane
Using the JOptionPane
Showing a warning or error message with this class is very simple:
JOptionPane.showMessageDialog(null, "Alert", "Warning",
JOptionPane.WARNING_MESSAGE);
12-22
12
The JOptionPane
Using the JOptionPane (Continued)
The four arguments are:
ERROR_MESSAGE
INFORMATION_MESSAGE
WARNING_MESSAGE
QUESTION_MESSAGE
PLAIN_MESSAGE
These types primarily dictate the icon that shows up in your dialog
window. (What icon you get depends on the look and feel youre
currently using.)
As you get comfortable with the message dialogs, you can experiment
with some of the other options available with JOptionPane. You can
create yes/no dialogs and even generic input dialogs.
Utility Panes
12-23
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
12
The JOptionPane
Using the JOptionPane (Continued)
As well as simple message dialogs, the JOptionPane is able to request
input from the user. The method showConfirmDialog is one of several
that provides this type of behavior. This example presents a threebutton window where the buttons display Yes, No, and Cancel.
You can determine which button the user pressed by examining the
returned value. The returned value will be zero, one, or two,
indicating yes, no, or cancel.
1 int response = JOptionPane.showConfirmDialog(
2
null,
3
"What next?",
4
"Choose your destiny",
5
JOptionPane.YES_NO_CANCEL_OPTION,
6
JOptionPane.INFORMATION_MESSAGE
7 );
8 switch (response) {
9 case 0:
10
jl.setText("Option was: YES");
11
break;
12 // ...
12-24
12
Exercise: Using the Utility Panes
Exercise objective Use the JTabbedPane, JScrollPane,
JSplitPane, and JOptionPane classes.
Preparation
Read the file README in the labs directory for module 12.
Run the program MultiEx in the solutions directory for module 12.
Examine all the panes in the tabbed pane, and all the dialog options.
Tasks
Edit the file MultiEx.java that contains the template for this exercise.
At each point where you find a line beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
Utility Panes
12-25
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
12
Exercise: Using the Utility Panes
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
12-26
Experiences
Interpretations
Conclusions
Applications
12
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
Utility Panes
12-27
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
12
Think Beyond
How would you create displays that have more than two split regions?
12-28
Program Localization
13
Course Map
This module discusses issues that arise when programming for
multiple languages and cultures.
Swing Introduction
Introduction
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
13-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
13
Relevance
Discussion What proportion of your programs will be run
exclusively by English speakers?
How many languages and cultural variations do you need to be able
to support if you create an applet for distribution on the World Wide
Web?
13-2
13
Objectives
Upon completion of this module, you should be able to:
Write code that reads properties from the invoking command line
Program Localization
13-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
13
13-4
13
Unicode and Other Character Sets
If InputStreamReader and OutputStreamWriter are constructed
with both a stream and a String, then the byte encoding used in
conversion is taken to be the encoding named in that String
argument. Legal encoding names are listed in the documentation of
the tool native2ascii. These are typically code page numbers from
Microsoft Windows platforms, and the ISO 8859 series.
When you write code that requires conversion between a byte stream
and a Unicode channel (Reader or Writer) be careful to decide
correctly what type of conversion is required. If the code is
communicating with the host system (keyboard, screen, or files, for
example) then you should probably convert to and from the host
platform encoding, using InputStreamReader and
OutputStreamWriter objects constructed without an explicit byte
encoding. If, however, you are communicating over a network with
hosts for which the byte encoding standard is unknown, then you
must be more careful. If you are writing new code for both ends of the
network, then you can use Unicode or UTF if you want to retain the
maximum flexibility. However, if you are only coding one end of the
system, perhaps a new client for an existing server, then you must
adopt the byte encoding of the other system. More often than not, this
will be ASCII, which is known to the JDK as ISO 8859_1 or 8859_1.
Program Localization
13-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
13
Localizing Code
Code might exhibit different appearances and perhaps even different
behaviors in different runs for a variety of reasons. The most
compelling and obvious of these is to support the different natural
languages spoken by users. Additionally, it might be valuable to be
able to use different message text for different companies, or to
suppress or modify some program functionality as a way of delivering
different product versions.
One very simple mechanism for controlling the behavior of a program
at runtime is to use Properties. The class java.util.Properties is
a class that extends Hashtable, and effectively stores values against
names. The runtime system has a Properties object, known as the
system properties. You can set properties in this table from the
command line using the -Dname=value option.
13-6
13
Localizing Code
You can create a property table of your own if you want, in which case
you can initialize it from a file using the
Properties.load(inputStream) method. In fact, this method can be
used to add properties to the system property table. Obtain a reference
to the system properties using the System.getProperties method
and then invoke the load method upon that object.
Note Imported code, such as an applet, cannot generally modify the
system property table. This restriction is imposed by the security
manager. Such code can create property tables for its own use,
however.
Once they are set, system properties may be read conveniently in a
variety of forms using methods in some of the java.lang classes. For
example, java.lang.System has a method getProperty that
returns the String value of a named property, Boolean has a
method getBoolean that returns the boolean value of a named
propertywhich would have been set using -DpropName=true, for
example. Similar convenience methods, including interpreting the text
format of the value, are available for integers, floating point numbers,
colors, and fonts.
Program Localization
13-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
13
Locale
Locale is a concept that has been in use for many years now, and is
also supported by the JDK. A locale describes the language and
country in which a program is running. Occasionally it may also
describe the host platform.
The JDK APIs have a class java.util.Locale that may be used to
describe locales, and forms the basic means of identifying countryspecific preferences that are used by other classes, such as those
handling dates.
You can obtain a reference to a Locale that describes the host
environment using the static method getDefault in the Locale
class.
13-8
13
ResourceBundle
Overview
You have seen that Properties can be used to input runtime
information, and Locale can be used to identify the host
environment. This still leaves a problem unsolved. How should you
implement the program dependencies that are conditional upon either
Properties or Locale?
Clearly one approach is to use if statements and conditional code.
Another, especially suitable for textual messages, is to build a file
name that is varied in some way by the property or locale settings.
That file then contains the correct versions of messages. For example, if
your Locale is British English (en_GB) you might load a file called
messages_en_GB.
Program Localization
13-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
13
ResourceBundle
Overview (Continued)
A more flexible mechanism for handling general locale dependencies
is embodied in the abstract class java.util.ResourceBundle. A
ResourceBundle is similar to a Hashtable in that it organizes a
collection of Object instances indexed by a String key field. For
each locale that is to be supported by the program, a new
ResourceBundle class is created. The name of the class should
reflect the Locale for which it is intended; for example,
Support_en_GB.
Provided that these naming conventions are used, you can obtain the
appropriate ResourceBundle for your programs current locale by
calling the static method getBundle(String rootname) in the
ResourceBundle class. The rootname provided should be the fully
qualified base class name, so that the locale description parts can be
added by simple extension.
For example, if you have created classes myloc.Support_en_GB,
myloc.Support_en_US, and myloc.Support_de_CH, you would
use a root class name of myloc.Support. Furthermore, if you
provide a class with just the root name, it will be used if more suitable
locale specific support cannot be found.
You can load a ResourceBundle for a specific locale, rather than the
default. This might be appropriate in response to a command line
option, since it would enable the user to override the system default.
13-10
13
ResourceBundle
Using a ResourceBundle
When you have located the correct ResourceBundle for your locale,
you can obtain data from it using three getXXX methods. Each
method takes a String argument which is the name of the particular
resource that you want to retrieve. Depending upon whether you are
trying to retrieve a String, an array of String objects, or some other
class, you should use the methods getString, getStringArray, or
getObject. Note that since arrays are actually Object instances this
third option is suitable for any data type, although it will require you
to cast the returned value appropriately.
Program Localization
13-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
13
ResourceBundle
Creating a ResourceBundle
There are several ways to obtain a suitable ResourceBundle for use in
a program. You can subclass the (abstract) class ResourceBundle, in
which case you must implement two methods. These are
handleGetObject(String key) and getKeys. The first of these
implements the actual retrieval mechanism, while the second must
return an Enumeration that lists all the keys that are known to this
particular bundle.
It is not difficult to implement these methods, and a Hashtable can
be used as the basis for an easy implementation, but in general, it is
easier to use one of the other subclasses such as the
ListResourceBundle.
13-12
13
ListResourceBundle
ListResourceBundle is a subclass of ResourceBundle. It is still
abstract, but there is only a single method that needs to be
implemented, which is the method getContents.
The getContents method should return an array of arrays of
Object. The sub-arrays should have two elements, where the first is
the key String, and the second is the actual Object associated with
the key.
Program Localization
13-13
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
13
Formatting Messages
Overview
Messages that are used by a Java program often need double
configuration. Different message text may be needed to support
different languages, and frequently those messages also need to have
runtime values substituted into them. For example a program might
need to report Today is January first or, in a different locale Au jour
dhui cest le premier Janvier. Clearly both messages contain a
constant part, and also two variable parts. To make it more
complicated, the variable parts occur in different orders.
To handle situations of this type, which amount to a locale-specific
template to be substituted with runtime values in a locale specific way,
you use the classes in the java.text package. The fundamental class
upon which all others build is the MessageFormat.
13-14
13
Formatting Messages
Basic Use of MessageFormat
The MessageFormat class has a static method format which is used
for most formatting. The method takes two arguments: one is a
template or format string, and the other is an array of Object
instances which supply the variable information to be patched into the
template String.
The template string can contain substitution placeholders.
Placeholders are contained in braces, and contain the index of the
value to be substituted. They might also contain information about
how to format the substitution and the type of the data.
For example, to indicate that the Object at index 2 in the argument
array is to be interpreted as a time, use a placeholder {2, time}
Program Localization
13-15
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
13
Formatting Messages
Localizing Formatted Messages
When a program needs to format messages, and those messages need
to be localized, you can use the ResourceBundle class to provide both
format strings and argument strings. Consider the following example:
ResourceBundle bundle =
ResourceBundle.getBundle("BalloonValues", here);
Object [] values = {
bundle.getString("colorname"),
new Integer(balloonCount),
new Date()
};
String template = bundle.getString("format");
System.out.println(
MessageFormat.format(template, values));
13-16
13
Formatting Messages
Localizing Formatted Messages (Continued)
Notice that the placeholders in a format string can refer to arguments
in any order. Individual arguments may be used any number of
timeszero, once, or more than once, as needed.
Program Localization
13-17
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
13
Formatting Messages
More Control of Message Formatting
The format information in placeholder braces may be any one of the
following:
time
date
number
choice
You will see in the following pages how each of these options can take
additional text to control the detail of the formatting involved.
13-18
13
Date Formatting
The time and date placeholder options may take any of the submodifiers: short, medium, long, and full, or an explicit
pattern describing exactly how the date should be shown. Each of
these four options will produce output that is dependent upon the
current locale, including using local languages for day and month
names and so forth. The full documentation on the explicit pattern
format is given in the documentation for the class
java.text.SimpleDateFormat.
Program Localization
13-19
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
13
Numeric Formatting
The number entry in a placeholder may be modified using any of the
following: currency, percent, integer, or an explicit pattern. As
with date and time, the first three options are also governed by the
current locale, and the full specification for the pattern format is given
in the documentation for the class java.text.DecimalFormat.
13-20
13
Choice Formatting
The ChoiceFormat class converts a double value into a String. You
construct a ChoiceFormat by providing an array of double values,
and a parallel array of String objects. The ChoiceFormat object then
converts a double argument into the corresponding String when you
call its format method, as follows:
double [] staffIDs = { 0.0, 1.0, 2.0, 3.0, 4.0 };
String [] staffNames = {
"Fred", "Jim", "Sheila", "Andy", "Chris"
};
ChoiceFormat staffFormat =
new ChoiceFormat(staffIDs, staffNames);
output = staffFormat.format(2);
Note Either or both of the parallel arrays can be retrieved from a
ResourceBundle.
Program Localization
13-21
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
13
Nested Formatting
Overview
Formats may be nested, so that one format refers to other subformats.
This can be useful with ChoiceFormat objects, since they only
perform limited formatting themselves, and you will usually need to
paste their output into another string. It is also a useful technique for
reusing formats and templates in multiple situations, and for breaking
down very complex formats into more manageable chunks.
To nest formats, first create the smaller subformats that will be
aggregated by the top-level format. Place these subformats into an
array, and put the arguments for them into another array. Then create
the top-level MessageFormat. This must be an actual instance of the
MessageFormat class; you cannot use the static format method this
time, as you need more control over the format process. Apply the
formats to the top level format by using the setFormats method,
then invoke the overall format operation by using the format
instance method of the MessageFormat class that takes only the
Object array for arguments.
13-22
13
Nested Formatting
Example
import java.text.*;
public class NestedForms {
public static void main(String args[]) {
double [] plurals = { 0.0, 1.0, 2.0 };
String [] pluralStrings = {"there are no files",
"there is one file",
"there are {1} files"};
ChoiceFormat plural =
new ChoiceFormat(plurals, pluralStrings);
MessageFormat dirMsg =
new MessageFormat("In directory {0} {1}");
Format [] dirForms = { null, plural };
dirMsg.setFormats(dirForms);
Object [] dirArgs = { "tools", null };
for (int fileCount = 0; fileCount < 4; fileCount++) {
dirArgs[1] = new Integer(fileCount);
System.out.println(dirMsg.format(dirArgs));
}
MessageFormat collected =
new MessageFormat("My friend {0} tells me {1}");
Format [] collectedForms = { null, dirMsg };
collected.setFormats(collectedForms);
Object [] collectedArgs = { "Ruth", dirArgs };
System.out.println(collected.format(collectedArgs));
}
}
Program Localization
13-23
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
13
Exercise: Program Localization
Exercise objective Become familiar with resource bundle usage.
Preparation
Read the file README in the labs directory for module 13.
Run the program Messages in the solutions directory. Choose
different locales each time you start the program, and observe that the
messages change accordingly.
Tasks
Edit the files Messages.java and WeatherMessages.java that
contains the template for this exercise. At each point where you find a
line beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
13-24
13
Exercise: Program Localization
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
Experiences
Interpretations
Conclusions
Applications
Program Localization
13-25
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
13
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
13-26
Write code that reads properties from the invoking command line
13
Think Beyond
What proportion of your programs relates to creating text messages?
How much of that can you now move outside of your source code?
Does this have any implications for maintenance?
Program Localization
13-27
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
13
13-28
14
Course Map
This module discusses the techniques needed to create new
components.
Swing Introduction
Introduction
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
14-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
14
Relevance
Discussion Do the components in the Swing set cover all possible
user interface requirements? Are there any special situations that
might require you to create a new component, either from scratch or
by modification of an existing component?
14-2
14
Objectives
Upon completion of this module, you should be able to:
14-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
14
Component Requirements
Once you have decided to create a new component, there are three key
features that you will need to program. These are the look, the
feel, and the event behavior.
14-4
Event behavior. The events that the component issues are used to
program its interactions with other components.
14
14-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
14
Creating a New Component
There is a potentially important issue to consider if you are creating a
new component that will be used in Swing GUIs, and that is Swings
pluggable look and feel. If you create a new component from scratch,
you will not have a pluggable look and feel for it, which means that if
the component is used in a GUI and the user then requests a different
look and feel, your component will not change its appearance.
Because of the look and feel issue, and the fact that it is usually easier,
extend existing Swing components, rather than start from scratch,
wherever possible.
14-6
14
Lightweight Components
Because lightweight components are rendered in Java code, and their
events are handled in Java code, you can rely on the semantics of
overriding methods such as paint or processEvent when you
create a subclass. In effect this means that subclassing a lightweight
component is a legitimate and reliable mechanism for producing a
new component with modified behavior.
Lightweight components do not have to be rectangular, nor opaque,
and they can use double buffering behavior inherited from the
java.awt.Component class if required.
To create a non-rectangular component, you must override the
contains methods to allow the parent container to dispatch mouse
entry and exit events properly. You also need to ensure that you create
a paint method that only draws the pixels that are actually part of the
component proper. The paint method will receive a Graphics object
that includes parts of screen area that are outside the components
boundaries (it will be a rectangular area). Restricted painting can be
easily achieved using the setClip(Shape) method of the Graphics
class.
14-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
14
Event Handling
Event handling is a crucial part of any component. Events carry
information about the users activities, and most components need to
react to user input at some time.
To program your components reaction to GUI events you should
enable the required event and override one or more of the
processEvent series of methods as appropriate. In the Component
class, the methods are:
protected
protected
protected
protected
protected
protected
void
void
void
void
void
void
processComponentEvent(ComponentEvent)
processFocusEvent(FocusEvent)
processInputMethodEvent(InputMethodEvent)
processKeyEvent(KeyEvent)
processMouseEvent(MouseEvent)
processMouseMotionEvent(MouseEvent)
14-8
14
Event Handling
Subclasses of Component may have additional methods for particular
event groups that apply to them.
Note You should not try to handle events by attaching yourself as a
listener to yourself. This is inefficient, and is subject to intervention by
other listeners or by further subclassing. Remember that the order in
which event listeners are called is not defined, so you might receive
the event last.
Event handling flows as follows:
1. An action occurs at the GUI (usually user initiated).
2. Locate the target component.
3. If that particular event is enabled for the target component, then
create an Event object to describe what happened and call the
processEvent.
4. The default processEvent method calls one of the other
processXXXEvent methods as appropriate to the type of event.
5. When processXXXEvent returns, call any registered listeners for
that event.
Events are enabled by calling the method enableEvents. This
method takes an argument that describes which category of events
you want to receive.
Note The addXXXListener methods in distribution components
ensures that the appropriate event is enabled. If you create an
addXXXListener method yourself, be sure to include the
enableEvents call.
14-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
14
Once these decisions had been made, you need to write some
methods. These have been seen already, but they are shown here for
reference. The methods you must write are the
add/removeXXXListener methods, and a convenience method for
firing the events.
14-10
14
Event Sourcing Methods
Recap
You need to add code to support the adding of listeners, and for firing
events to those listeners. This was discussed in detail in on page 61 in Module 6, Models, Views, and Controllers but for convenience
the template code for these key aspects is shown here too.
14-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
14
Creating a New Component
1 import java.awt.*;
2 import java.awt.event.*;
3 import com.sun.java.swing.*;
4 import java.util.*;
5
6 public class XYInput extends JComponent {
7
private Vector listeners = new Vector();
8
private Point clickedAt;
9
10 public XYInput() {
11
enableEvents(AWTEvent.MOUSE_EVENT_MASK);
12
setPreferredSize(new Dimension(256, 256));
13 }
14
15 public XYInput(Dimension d) {
16
this();
17
setPreferredSize(d);
18 }
19
20 public XYInput(int w, int h) {
21
this(new Dimension(w, h));
22 }
23
24 protected void processMouseEvent(MouseEvent ev) {
25
if (ev.getID() == MouseEvent.MOUSE_CLICKED) {
26
clickedAt = ev.getPoint();
27
XYEvent e = new XYEvent(this, clickedAt);
28
sendEvent(e);
29
repaint();
30
}
31
super.processMouseEvent(ev);
32 }
33
14-12
14
Creating a New Component
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
14-13
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
14
Creating a New Component
58 // this main acts as a test harness only
59 public static void main(String args[]) {
60
JFrame f = new JFrame("XY test");
61
final JTextField t = new JTextField();
62
XYInput xy = new XYInput(400, 400);
63
Container c = f.getContentPane();
64
c.add(t, BorderLayout.SOUTH);
65
c.add(xy, BorderLayout.CENTER);
66
xy.addXYListener(
67
new XYListener() {
68
public void pointSet(XYEvent e) {
69
Point p = e.getPoint();
70
t.setText("Click at " + p.x + ", " + p.y);
71
}
72
}
73
);
74
f.pack();
75
f.setVisible(true);
76 }
77 }
78
79 // This interface should be public. It is in this file for convenience
80 interface XYListener {
81 public void pointSet(XYEvent e);
82 }
83
14-14
14
Creating a New Component
84 // This class should be public. It is in this file for convenience
85 class XYEvent extends AWTEvent {
86 private Point p;
87
88 public XYEvent(Object source, Point p) {
89
super(source, 0);
90
this.p = p;
91 }
92
93 public Point getPoint() {
94
return p;
95 }
96 }
97
14-15
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
14
Exercise: Create a New Component
Exercise objective Create a non-rectangular component that
responds to both keyboard and mouse input.
Preparation
Read the file README in the labs directory for module 14.
Run the program XYKeyInput in the solutions directory. Investigate
its response to the arrow keys and the keys h, j, k, and l. Note the effect
of pressing these keys while holding the Shift key down. Observe the
effect of clicking the mouse both inside and outside of the blue region.
Tasks
Edit the file XYKeyInput.java that contains the template for this
exercise. At each point where you find a line beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
14-16
Check for the nature of a key event, both the key value and
whether this is a key being pressed or released
Take part in focus traversal when the user presses the Tab key to
select the next focusable component
14
Exercise: Create a New Component
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
Experiences
Interpretations
Conclusions
Applications
14-17
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
14
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
14-18
14
Think Beyond
What sort of custom components can you think of that you might be
called upon to create?
14-19
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
14
14-20
15
Course Map
This module discusses the implementation of copy-and-paste and
drag-and-drop features in user interfaces.
Swing Introduction
Introduction
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
15-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
15
Relevance
Discussion Will your users accept an interface that does not support
cut-and-paste? How will they feel about a drag-and-drop feature?
15-2
15
Objectives
Upon completion of this module, you should be able to:
15-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
15
Data Types
There are two main mechanisms for users to initiate data transfer
using the GUI. These are copy-and-paste, and drag-and-drop. The
most fundamental aspect of both is that the data to be transferred must
be packaged in a format that is comprehensible to the receiver.
Data comes in many forms. GUIs commonly display text, references to
files, URLs, images and more. The JDK data transfer mechanisms use
the java.awt.data transfer.DataFlavor class to represent the
type of data during a GUI data transfer operation. The DataFlavor
class itself uses MIME types to represent data types, since MIME is a
well known and expressive standard for this.
15-4
15
Data Types
Often, the originator of a GUI data transfer might be able to offer its
data in multiple formats. For example, dragging from a JTextPane
could offer a Document object, which would fully represent all detail of
the source data, including styles; a String, which would retain full
Unicode characters, but not the styles; or plain (ASCII) text which
would lose any non 8-bit characters. Clearly this observation involves
a preference order, the data are best represented in a particular way,
but useful information can be extracted by looking at the data in some
other way.
In the same way that the source of a data transfer might offer multiple
data types, with a preference ordering, so the receiver will also have a
list of acceptable types, and a preference order associated with them.
Whenever a transfer is attempted, the source and destination must
agree on the format that the transfer is to take place using. If no
common types exist, then the transfer cannot take place.
15-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
15
15-6
15
15-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
15
Paste From Clipboard
Example
1
2
3
4
5
6
7
8
9
import java.awt.datatransfer.*;
// this is a Component instance
Clipboard c = getToolkit().getSystemClipboard();
Transferable t = c.getContents(this);
DataFlavor [] flavors = t.getTransferDataFlavors();
for (int i = 0; i < flavors.length; i++) {
try {
Object o = t.getTransferData(flavors[i]);
System.out.println("Flavor " + i + " gives "
+ o.getClass().getName());
10
if (o instanceof String) {
11
text.setText((String)o);
12
}
13
}
14
catch (Exception ex) {
15
ex.printStackTrace();
16
}
17 }
Note This code fragment assumes that the this object is a text
component of some sort.
15-8
15
Copy to Clipboard
Overview
To put data into the system clipboard, a component should follow this
sequence of operations. Each step references a line in the example on
page 15-10.
1. Obtain a reference to the system clipboard (line 3).
2. Create a Transferable object that represents the data and the forms
in which it can be viewed (line 6).
3. Apply the data to the clipboard (line 7).
15-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
15
Copy to Clipboard
Overview (Continued)
When setting the data in the clipboard, you need to provide a
ClipboardOwner object. ClipboardOwner is an interface that
defines a method void lostOwnership(Clipboard,
Transferable). If some other program writes into the clipboard, the
lostOwnership method will be called, allowing you the chance to
preserve the Transferable you created, or otherwise react as you
might need. You might want to use this to abandon your reference to
the data, allowing it to be garbage collected.
In this example, the StringSelection class represents the data.
This class is suitable for use where a Java String is being passed
around, and it offers two flavors, either a Unicode string or an ASCII
string.
In many cases you will need to represent other forms of data. To
achieve this you must create a different type of Transferable.
Example
1 import java.awt.datatransfer.*;
2 class ... implements ClipboardOwner {
3
4
5
6
7
Clipboard c = getToolkit().getSystemClipboard();
// Create a Transferable to put into the clipboard
// StringSelection is simplest, and pre-defined
StringSelection ss = new StringSelection(text.getText());
c.setContents(ss, this);
8
9
10
15-10
15
Implementing Transferable
The Transferable interface defines three methods:
Object getTransferData(DataFlavor)
throws UnsupportedFlavorException
DataFlavor [] getTransferDataFlavors()
boolean isDataFlavorSupported(DataFlavor)
If you need to create a new Transferable class to support some data
type, you must implement these methods.
The first of these methods must return the data, in the format
requested. If the requested flavor is not possible, then an
UnsupportedFlavorException should be thrown.
15-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
15
Implementing Transferable
To avoid causing exceptions, the caller of the getTransferData
method should determine in advance if a flavor is achievable. The
other two methods are provided for this purpose.
getTransferDataFlavors should return an array, in preference
order, of all flavors this Transferable can use, and
isDataFlavorSupported should simply return true or false to
indicate if the particular flavor is possible.
15-12
15
Exercise 1: Implementing Cut-and-Paste
Exercise objective Implement cut-and-paste with text data.
Preparation
Read the file README.1 in the labs directory for module 15.
Run the program CutPaste in the solutions directory. Use the cut
and paste buttons, and cut and paste from other programs in your
system. This will show you the required behavior for your solution.
Tasks
Edit the file CutPaste.java that contains the template for this
exercise. At each point where you find a line beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
15-13
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
15
Exercise 1: Implementing Cut-and-Paste
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
15-14
Experiences
Interpretations
Conclusions
Applications
15
Drag-and-Drop
Comparison With Cut-and-Paste
There are many parallels between the cut-and-paste and the drag-anddrop concepts. In both, a data block is moved from a source GUI
feature to a destination GUI feature. In both cases there must be a
representation of that data block, and the concept of data flavor
applies equally to both.
However, there are also some differences. Drag-and-drop is somewhat
more automatic. When a component pastes from the clipboard, it is
that component (typically) that initiates the process. By contrast, with
drag-and-drop, the sourcing and destination process both really start
when the user clicks and drags using the mouse. At that point, it is
unclear where the target of the drop might be.
During dragging, there may be some additional behavior. For
example, the mouse cursor will usually change, or some aspect of the
program might need callbacks to monitor the progress of the drag.
15-15
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
15
Drag-and-Drop
X Windows Mechanisms
On UNIX systems running X Windows, a potential complication
arises. There are two distinct drag-and-drop mechanisms defined for X
Windows, and they are incompatible. The drag-and-drop mechanism
used by the JDK is compatible only with the Motif/CDE system. If you
use OpenLook window manager or OpenLook programs, drag-anddrop between those systems and Java programs will not work.
Drag-and-Drop Actions
Drag-and-drop can perform more than one action. You might copy a
file, or you might move it. You might, in some systems, even create a
link or shortcut to the file. These different possibilities are referred
to as actions. Usually, the user indicates the desired action by using
keys, such as Shift, Control and so forth, during the drag.
There are three distinct parts of the drag-and-drop system that might
influence the action that is performed; these are the drag source, drag
target, and the user. Ideally, the final action should be the one chosen
by the user. However, if the user attempts to invoke an action that the
source cannot support, then the action will be modified accordingly. In
such a case, the mouse cursor will indicate what action is being
prepared. Similarly, if the proposed action is unacceptable to the drop
target, then it can be rejected.
15-16
15
dragEnter(DropTargetDragEvent)
dragExit(DropTargetEvent)
dragOver(DropTargetDragEvent)
dropActionChanged(DropTargetDragEvent)
drop(DropTargetDropEvent)
These methods are the target of callbacks that are made as the drag
proceeds. The most important of these is the drop method, which is
called when the user finally commits the drop operation over the
Component that is associated with this DropTargetListener.
15-17
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
15
DropTarget and DropTargetListener
Accepting or Rejecting the Drop
As a drag proceeds, the various methods of the DropTargetListener
are invoked and an event is passed to them. The event carries the
Transferable and information about the drag, such as the proposed
drop action.
The listener methods should be coded so that they examine the
proposed drop and decide if it is appropriate to the target. This
decision might be made on the basis of the Transferable or the
proposed action. If a proposed drop is acceptable, you should call the
acceptDrag method of the DropTargetDragEvent, or the
acceptDrop method of the DropTargetDropEvent (according to the
method argument) indicating what action you are accepting. The
proposed action can be determined by calling the getDropAction
method of either event.
As the drag proceeds the mouse cursor will indicate if the proposed
drop is being accepted or rejected. Because this mouse behavior is
triggered by the acceptDr?? and rejectDr?? methods it is important
that you call them appropriately.
15-18
15
DropTarget and DropTargetListener
Example
1 import java.awt.*;
2 import java.awt.dnd.*;
3 import java.awt.datatransfer.*;
4 import java.io.*;
5
6 public class DroppableList extends List
7
implements DropTargetListener{
8
9
public DroppableList() {
10
// this is both target component and listener
11
new DropTarget (this, this);
12 }
13
14 private void validateDrag(DropTargetDragEvent e) {
15
int action = e.getDropAction();
16
if (action == DnDConstants.ACTION_MOVE) {
17
e.acceptDrag(action);
18
}
19
else {
20
e.rejectDrag();
21
}
22 }
23
24 public void dragEnter(DropTargetDragEvent e) {
25
validateDrag(e);
26 }
27
28 public void dragOver(DropTargetDragEvent e) {
29
validateDrag(e);
30 }
31
32 public void dropActionChanged(DropTargetDragEvent e) {
33
validateDrag(e);
34 }
35
36 public void dragExit(DropTargetEvent e) { }
37
15-19
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
15
DropTarget and DropTargetListener
Example (Continued)
38 public void drop(DropTargetDropEvent e) {
39
int action = e.getDropAction();
40
Transferable tr = e.getTransferable();
41
if ((action == DnDConstants.ACTION_MOVE) ||
42
tr.isDataFlavorSupported(DataFlavor.stringFlavor)) {
43
e.acceptDrop(action);
44
try {
45
String s = (String)tr.getTransferData (
46
DataFlavor.stringFlavor);
47
add (s);
48
e.dropComplete(true);
49
}
50
catch (Exception ex) {
51
e.rejectDrop();
52
}
53
}
54
else {
55
e.rejectDrop();
56
}
57 }
58 }
15-20
15
15-21
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
15
DragSource, DragSourceListener, and
DragGestureListener
Overview (Continued)
Once the drag is started, the DragGestureRecognizer calls the
method dragGestureRecognized in the DragGestureListener
object. This method then starts the drag itself. This is achieved by
calling the startDrag method of the DragSource object. There are a
number of overloaded versions of this method, but the most likely one
to call expects four arguments:
15-22
15
DragSource, DragSourceListener, and
DragGestureListener
Example
1 import java.awt.*;
2 import java.awt.dnd.*;
3 import java.awt.datatransfer.*;
4
5 public class DraggableLabel extends Label
6
implements DragSourceListener, DragGestureListener {
7
8
DragSource dragSource;
9
public DraggableLabel(String s) {
10
super(s);
11
dragSource = new DragSource();
12
dragSource.createDefaultDragGestureRecognizer(
13
this, DnDConstants.ACTION_MOVE, this);
14 }
15
16 public void dragGestureRecognized(DragGestureEvent e) {
17
StringSelection text = new StringSelection(getText());
18
// specify null for the DragSourceListener if you are
19
// not interested in the callbacks.
20
dragSource.startDrag(
21
e, DragSource.DefaultCopyDrop, text, this);
22 }
23
24 // if no callbacks needed, you do not have to implement
25 // DragSourceListener at all.
26 public void dragDropEnd(DragSourceDropEvent e) { }
27 public void dragEnter(DragSourceDragEvent e) { }
28 public void dragExit(DragSourceEvent e) { }
29 public void dragOver(DragSourceDragEvent e) { }
30 public void dropActionChanged(DragSourceDragEvent e) { }
31 }
15-23
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
15
Exercise 2: Implementing Drag-and-Drop
Exercise objective Implement drag-and-drop with text data.
Preparation
Read the file README.2 in the labs directory for module 15.
Run the program DragDrop in the solutions directory. Drag and
drop between this and other programs in your system. This will show
you the required behavior for your solution.
Tasks
Edit the file DragDrop.java that contains the template for this
exercise. At each point where you find a line beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
15-24
15
Exercise 2: Implementing Drag-and-Drop
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
Experiences
Interpretations
Conclusions
Applications
15-25
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
15
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
15-26
15
Think Beyond
What reusable components can you create for use with GUI data
transfer?
15-27
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
15
15-28
16
Course Map
This module discusses the use of the GridBagLayout in the
production of complex user interfaces.
Swing Introduction
Introduction
Swing Foundations
Basic Swing
Components
More Swing
Foundations
Printing
JDK 1.2 Printing
Swing MVC
Components
Text in Swing
Text Editing
with Swing
Utility Panes
Creating Custom
Components
GUI Data
Transfer
Using the
GridBagLayout
16-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
16
Relevance
Discussion Can you create a GUI without using a layout manager?
Are there any drawbacks to this?
Can you create all reasonable layouts using only Flow, Grid, and
Border layouts?
16-2
16
Objectives
Upon completion of this module, you should be able to:
16-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
16
Layout Managers
JavaGUIs should make extensive use of layout managers, since the
alternative, absolute positioning by pixel coordinates, is not platform
portable. Issues such as the sizes of fonts and screens ensure that a
layout that is correct based on coordinates will be unusable on any
other platform.
Layout managers avoid these difficulties by laying out the GUI
according to a policy. For example the policy of the GridLayout is to
position child components in equal-sized cells, starting at the top left
and working left to right, top to bottom until the grid is full.
This course assumes you know about the basic three layout managers,
FlowLayout, GridLayout, and BorderLayout. If you are unsure about
any of these, ask your instructor if you can discuss them during a
break.
16-4
16
Layout Managers
If you do know the basic three layout managers, you will also know
that they are somewhat limited in their capabilities, and that it can be
quite hard work, often involving many nested panels, to produce a
layout that is useful in a production program. This module looks at the
GridBagLayout, which is more powerful.
16-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
16
The GridBagLayout
The GridBagLayout lays out components using a grid. However,
unlike the GridLayout, child components are not necessarily
constrained to occupy the exactly one entire grid cell, neither are all
rows and columns equal in size. Rather, a component can be assigned
multiple cells, horizontally, vertically, or both, and can exist within that
region.
16-6
16
The GridBagLayout
Figure 16-1
16-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
16
The GridBagLayout
Figure 16-2
16-8
16
The GridBagLayout
Figure 16-3
Where a component does not fill the entire region allocated to it, its
position within that region can be controlled using a concept called
anchor. Anchor takes one of nine values. Eight of these values are
compass points, NORTH, SOUTHWEST and so on. The ninth is CENTER. If
a component has its natural size and an anchor of NORTHWEST, then it
will be positioned at the top left of its allocated region.
In Figure 16-3, the two examples have differing anchor settings.
Specifically, the button labelled 5 has a CENTER anchor in the lefthand example, but a SOUTH anchor in the right-hand example. The
button labelled 8 has a CENTER anchor in the left-hand example, but
a WEST anchor in the right-hand example.
Clearly, there is some interaction between anchor and the fill of a
component. If the fill specifies that the component occupies the entire
region alloted to it, then anchor has no significance. If the fill value
specifies that a component occupies the allocated region entirely in the
horizontal direction, then the only anchor values that are useful are
NORTH, CENTER, and SOUTH. Any east-ness or west-ness will be
ineffective in such circumstances.
16-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
16
16-10
gridx and gridy. These integer fields are used to specify the row
and column numbers at the top left of the components region.
They are effectively the components coordinates.
fill. This field indicates how the component is sized within its
region. Values for this field are constants in the
GridBagConstraints class. The four symbolic values are: NONE,
HORIZONTAL, VERTICAL, BOTH.
16
The GridBagConstraints Class
Note Avoid setting weights on the same row or column for more
than one component. Doing so will simply serve to confuse anyone
reading the program.
16-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
16
16-12
16
Designing With GridBagLayout
Design Steps (Continued)
5. Now you have designed the underlying grid and you can proceed
to position each component over that grid. Start by identifying the
top left row and column for each component region; this gives you
the gridy and gridx values for each.
6. Next, determine the width and height of the region in terms of
columns and rows; these are the gridwidth and gridheight
values.
7. For each component, consider how it occupies the region allocated
to it. If it fills the region entirely, it has a fill value of BOTH. If it
fills the region from side to side but not vertically, then its fill
value is HORIZONTAL. If it fills its region vertically but not
horizontally, then its fill value is VERTICAL. If it does not fill the
region in either direction, then its fill value is NONE.
8. For each component, consider how it is positioned within the
region allocated to it and hence the anchor value for the
component. If a component has a fill value of BOTH then the
anchor value is irrelevant. Components with HORIZONTAL fill
should have an anchor of NORTH, CENTER, or SOUTH. Components
with VERTICAL fill should be anchored WEST, CENTER, or EAST.
Components with a fill of NONE, can have an anchor of any of
the nine values.
9. You now have all the key values required to set up your layout.
All that remains is to add the components and allocate the weights
to the rows and columns. You should choose one component for
each row and one component for each column to supply the
weight values. These components should be chosen so that they
only occupy one column if they are providing weightx, and one
row if they are providing weighty. If possible, use components on
the top row to specify weightx and components in the left column
to specify weighty.
16-13
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
16
Designing With GridBagLayout
Example
16-14
16
Designing With GridBagLayout
Example (Continued)
0
0
1
2
3
4
5
6
Extra column
4
0
1
2
4
5
6
Loose component
Next, draw on the gridlines and identify how the stretch is allocated.
There are a number of points to note here.
16-15
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
16
Designing With GridBagLayout
Example (Continued)
The expanded version brings out the existence of an extra column,
which is not really noticeable until the display is expanded. You would
be unlikely to recognize this columns existence in the unexpanded
diagram.
The loose component in column 0, third down, does not match any
of the grid cell boundaries. Rather, it appears to overlap rows 4 and 5.
The component actually is located in a region that extends over rows 3
through to 6 inclusive, and is vertically centered in that region.
Columns 0, 2, and 4 do not change size, but columns 1 and 3 do
stretch. It is not entirely clear how the space is shared, but a reasonable
working guess is that new space is allocated equally between them.
Rows 0, 1, and 6 do not change size, but rows 2 through 5 all stretch
equally.
16-16
16
Designing With GridBagLayout
Example (Continued)
1
2
5
8
10
11
12
gridx
1
2
3
4
5
6
7
8
9
10
11
12
0
0
1
2
3
0
1
4
4
4
4
0
gridy
0
1
1
1
1
2
2
2
3
4
5
6
gridwidth
5
1
1
1
2
1
3
1
1
1
1
5
gridheight
1
1
1
1
1
4
4
1
1
1
1
1
16-17
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
16
Designing With GridBagLayout
Example (Continued)
1
2
5
8
9
10
11
12
The next stage in designing the layout is to determine the fill and
anchor values for the components.
The fill value should be BOTH for all components that take the full size
of their available regions. This is important even if the region does not
stretch. For example, the cells occupied by components 8, 9, 10, and 11
do not stretch horizontally, so you might think that a horizontal
component of fill was unnecessary. However, if you only specify a fill
of VERTICAL, you will find that the components are given their
preferred sizes, and since their labels are shorter, components 8 and 9
will be slightly smaller than components 10 and 11.
So, in this example, the only component that is not set to fill BOTH is
component 6. This should have a fill value of HORIZONTAL, to ensure
that it takes up the full width of its region.
Anchor values are only significant where a components region is
larger than the component itself. In this example, this applies only to
component 6. Here the component must be centered vertically,
although it fills the available width. In consequence, any of the anchor
values EAST, WEST, or CENTER would result in the required behavior,
but CENTER is probably the most reasonable since it most directly
expresses the required result.
16-18
16
Designing With GridBagLayout
Example (Continued)
0
0
1
1
2
5
8
10
11
12
16-19
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
16
Designing With GridBagLayout
Example (Continued)
Components 8, 9, 10, and 11 are suitable to apply the vertical weight
values for rows 2 through to 5, and component 3 is appropriate to
apply the horizontal weight for column 1. However, there is no
obvious component with which a horizontal weight can be applied to
column 3.
One way to approach this is to add a dummy component to the cell at
row 2, column 3. This component must have zero by zero size so that
it does not obscure component 8. A Canvas is suitable for this because
its preferred size is zero by zero, unless explicitly set otherwise. Once
added into row 3 column 4, it will remain at zero size provided it has
a fill value of NONE.
16-20
16
Designing With GridBagLayout
Example (Continued)
16-21
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
16
Designing With GridBagLayout
Example (Continued)
The main part of the program from this example, with the values used
in the GridBagConstraints, is shown here.
1 import java.awt.*;
2 import javax.swing.*;
3
4 public class ExampleGB {
5
public static void main(String args[]) {
6
JFrame f = new JFrame("GridBag Example");
7
Container c = f.getContentPane();
8
c.setLayout(new GridBagLayout());
9
GridBagAdder.add(c, new Canvas(), 3, 2, 1, 1, 1, 0,
10
GridBagConstraints.NONE, GridBagConstraints.CENTER);
11
GridBagAdder.add(c, new JButton("1"), 0, 0, 5, 1, 0, 0,
12
GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER);
13
GridBagAdder.add(c, new JButton("2"), 0, 1, 1, 1, 0, 0,
14
GridBagConstraints.BOTH, GridBagConstraints.CENTER);
15
GridBagAdder.add(c, new JButton("3"), 1, 1, 1, 1, 1, 0,
16
GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER);
17
GridBagAdder.add(c, new JButton("4"), 2, 1, 1, 1, 0, 0,
18
GridBagConstraints.BOTH, GridBagConstraints.CENTER);
19
GridBagAdder.add(c, new JButton("5"), 3, 1, 2, 1, 0, 0,
20
GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER);
21
GridBagAdder.add(c, new JButton("6"), 0, 2, 1, 4, 0, 0,
22
GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER);
23
GridBagAdder.add(c, new JButton("7"), 1, 2, 3, 4, 0, 0,
24
GridBagConstraints.BOTH, GridBagConstraints.CENTER);
25
GridBagAdder.add(c, new JButton("8"), 4, 2, 1, 1, 0, 1,
26
GridBagConstraints.BOTH, GridBagConstraints.CENTER);
27
GridBagAdder.add(c, new JButton("9"), 4, 3, 1, 1, 0, 1,
28
GridBagConstraints.BOTH, GridBagConstraints.CENTER);
29
GridBagAdder.add(c, new JButton("10"), 4, 4, 1, 1, 0, 1,
30
GridBagConstraints.BOTH, GridBagConstraints.CENTER);
31
GridBagAdder.add(c, new JButton("11"), 4, 5, 1, 1, 0, 1,
32
GridBagConstraints.BOTH, GridBagConstraints.CENTER);
33
GridBagAdder.add(c, new JButton("12"), 0, 6, 5, 1, 0, 0,
34
GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER);
35
f.pack();
36
f.setVisible(true);
37 }
16-22
16
Designing With GridBagLayout
Example (Continued)
Supporting the code on the previous page is this inner class. It
provides the add method that simplifies setting up the
GridBagConstraints values.
38 static class GridBagAdder {
39
// OK to reuse this as we overwrite all elements every time
40
// Note that this is not threadsafe however!
41
static GridBagConstraints cons = new GridBagConstraints();
42
public static void add(Container cont,Component comp,int x, int y,
43
int width,int height,int weightx,int weighty,
44
int fill,int anchor) {
45
46
cons.gridx = x;
47
cons.gridy = y;
48
cons.gridwidth = width;
49
cons.gridheight = height;
50
cons.weightx = weightx;
51
cons.weighty = weighty;
52
cons.fill = fill;
53
cons.anchor = anchor;
54
cont.add(comp, cons);
55
}
56 }
57 }
16-23
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
16
16-24
16
RELATIVE and REMAINDER
Careful use of these shorthand features can make code easier to write
and smaller, which can make it easier to read. However, in some
situations, the fact that their use makes the layout dependent upon the
order of adding components might actually make code more difficult
to read.
16-25
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
16
Exercise: Using GridBagLayout
Exercise objective Implement a GUI layout using GridBagLayout.
Preparation
Read the file README in the labs directory for module 16.
Run the program Layout in the solutions directory for module 16.
Resize the window and observe the dynamic behavior of this layout.
This shows you how your layout should behave.
Tasks
Edit the file Layout.java that contains a template for this exercise. At
each point where you find a line beginning:
//****
write the code necessary to implement the comment at that point.
The commented parts of the source will add or complete the following
behavior:
16-26
16
Exercise: Using GridBagLayout
Exercise Summary
Discussion Take a few minutes to discuss what experiences, issues,
or discoveries you had during the lab exercises.
Experiences
Interpretations
Conclusions
Applications
16-27
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
16
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
16-28
16
Think Beyond
Are there any layout effects that you cannot handle using the layout
managers discussed in this module?
16-29
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
16
16-30
This appendix describes the delegation event model used in JDK 1.1
that is fundamental to the operation of Swing.
A-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
A
Relevance
Discussion Do you know about the delegation event model used by
JDK 1.1 and beyond?
A-2
A
Objectives
Upon completion of this appendix, you should be able to:
Describe the JDK 1.1 event delegation model and write code based
on it to allow a user interface Input component, such as a button,
to cause code of your choice to be executed
A-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
A-4
A-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
A
What is Event Handling?
Listeners Must Be Registered
To be called, a listener method must be registered in advance with the
object that issues the event. This might seem tedious, but the benefit is
that events are only passed to, and hence only processed by, interested
parties.
Note This compares favorably with the JDK 1.0 model which had
every user interface event processed by each container in a GUI
hierarchy by default.
A-6
A-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Event Classes
Overview
The AWT system and Swing use many pre-defined events. The
majority of these are in the package java.awt.event.
Note Be careful to distinguish the package java.awt.event from
the class java.awt.Event. java.awt.Event was used in the older
JDK 1.0 event model and is not relevant to the 1.1 model.
A-8
A
Event Classes
Event Utility Methods
You should take time to familiarize yourself with the variety of events
that are used by AWT and Swing classes. All delegation events,
whether related to GUI functionality or not, are subclasses of
java.util.EventObject. Each class provides utility methods for
accessing the specific information that it carries, for example a
keystroke can issue a KeyEvent which provides the method
getKeyChar() to extract the particular key that was pressed.
A particularly important method is defined in the
java.util.EventObject class itself, and this is the method
public Object getSource()
The getSource() method returns the source of the event, so in a GUI
environment, this is the GUI component originally affected.
A-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
A
Check Your Progress
Before continuing on to the next appendix, check that you are able to
accomplish or answer the following:
A-10
Describe the JDK 1.1 event delegation model and write code based
on it to allow a user interface Input component, such as a button,
to cause code of your choice to be executed
Printing
B-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
B
Relevance
Discussion What proportion of your programs require the ability to
create hard-copy output? What features are important when creating
printed output?
B-2
B
Objectives
Upon completion of this appendix, you should be able to:
Printing
B-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
AWT Printing
Overview
Printing with the AWT (JDK 1.1) mechanism is quite simple. Printed
output is generated when something draws onto a special Graphics
object that is associated with the printer.
Components have a print(Graphics) and printAll(Graphics)
methods, parallel in principle to the paint(Graphics) and
paintAll(Graphics) methods. This method should be coded to
render a suitable image of the component when called. This might
happen automatically if, for example, the print button of a browser is
used.
Note The paintAll and printAll methods are used to render not
just the individual component, but also any contained components in
a container.
B-4
B
AWT Printing
Overview (Continued)
It is common and simple to implement the print method by simply
invoking the paint method, like this:
1 public void print(Graphics g) {
2
paint(g);
3 }
Note This might not work with heavyweight components, where the
drawing is delegated to the peer.
This would result in the printed output closely matching the screen
version; an equivalent approach can be used for printAll using
paintAll. If you wish to have the printed version look different
(perhaps using different colors, textures, or fonts) then you would
implement a more complex print method.
If you are creating your own print button in a user interface then you
need to construct a suitable Graphics and either call the print or
printAll method. A Graphics object that refers to the printer, rather
than to the screen is obtained by the following steps:
1. Obtain a reference to the system Toolkit. This may be done by
using the getToolkit method of any visible component.
Alternatively, if no suitable components exist, you can use the
static method Tookit.getDefaultToolkit.
2. The Toolkit has a method getPrintJob which returns an
instance of a PrintJob. Call the getPrintJob method providing
a Frame instance and a title for the job. The user is presented with
a dialog that allows them to choose the destination of the printed
output. The call returns when the user clicks either the OK or
Cancel button on this dialog. A null return indicates the job was
cancelled.
3. If a non-null PrintJob has been obtained, invoke the method
getGraphics upon it. This returns a Graphics object that will
output onto a page of printed output.
Printing
B-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
B
AWT Printing
Overview (Continued)
4. For each successive output page that is required, call the dispose
method on the previous Graphics, and then call getGraphics
on the PrintJob again.
5. Finally, when all required pages have been output, call the end
method of the PrintJob. This causes the spooled output to be
submitted as a job to the printer.
B-6
B
AWT Printing
Example
1 import java.awt.*;
2 import javax.swing.*;
3 import java.awt.event.*;
4
5 public class AWTPrint {
6
public static void main(String args[]) {
7
final JFrame f = new JFrame("AWTPrint");
8
JButton b = new JButton("Print");
9
final JTextArea ta = new JTextArea("Some example text", 10, 40);
10
f.getContentPane().add(b, BorderLayout.NORTH);
11
f.getContentPane().add(ta, BorderLayout.CENTER);
12
13
b.addActionListener(
14
new ActionListener() {
15
public void actionPerformed(ActionEvent e) {
16
Toolkit k = ((Component)(e.getSource())).getToolkit();
17
PrintJob pj = k.getPrintJob(f, "Print Job", null);
18
if (pj != null) {
19
while (morePages()) { // ficticious boolean method
20
Graphics g = pj.getGraphics(); // get a page
21
g.setClip(new Rectangle(0, 0, 72*9, 72*11));
22
ta.paintAll(g);
23
Font font = new Font("Serif", Font.ITALIC, 24);
24
g.setFont(font);
25
g.setColor(Color.black);
26
g.drawString("Page 1", 40, 440);
27
g.dispose();
28
g = pj.getGraphics();
29
g.setFont(font);
30
g.setColor(Color.black);
31
g.drawString("Page 2", 40, 440);
32
g.dispose();
33
}
Printing
B-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
B
AWT Printing
Example (Continued)
34 pj.end(); // submit whole job
35
}
36
}
37
}
38
);
39
40 f.setSize(400, 400);
41
f.setVisible(true);
42 }
43 }
B-8
Printing
B-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
B
Check Your Progress
Before continuing on to the next appendix, check that you are able to
accomplish or answer the following:
B-10
This appendix outlines the method for adding new fonts, such as nonRoman alphabet fonts, to a Java technology runtime (Java runtime)
system.
C-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
C
Relevance
Discussion If you are writing programs that will run in a variety of
locales, how can you test them with multiple language fonts?
C-2
C
Objectives
Upon completion of this module, you should be able to:
Install new fonts, and configure font aliases for use in either
Solaris or Microsoft Windows JDK/JRE environments
C-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Adding Fonts
The JVM runtime system allows you to install as many fonts into a
runtime as you need, although by default only four basic families are
configured. Your programs can determine what font families are
available by using the getFontlist method of the Toolkit class.
If you need to, you can add new fonts. This might be necessary to
allow you to test a program under a locale that is different from your
normal one. You can do two things; you can add aliases, which might
allow you to get a program working even if it requests a font family
that you do not have; and you can install new fonts for an existing
family, or install entirely new fonts.
Installing a new font into an existing family might be needed since
most font distributions do not actually contain glyphs for all the
characters in the Unicode set. If you need to display more characters,
you need to locate a font that has the required glyphs and install that.
C-4
C
Adding Fonts
A common problem is that the characters in a font might not be
indexed using Unicode. In such situations, the process of installing the
font also involves installing index translators so that the right glyph
can be found.
C-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Font Configuration
Font configuration is generally governed by a file called
font.properties. This file is located in the jre/lib directory just
beneath the main installation directory of your JDK or JRE. In some
cases, a special file named like font.properties.XX might be
used. This would occur if the XX part matched the current locale; for
example, in a Japanese locale the file font.properties.ja is used.
Creating an alias is quite simple. In the appropriate font.properties
file, just create an entry of this form:
alias.aliasname=existingfontname
Such entries are already present in the distribution
font.properties files. They support the old font names
(TimesRoman, Courier and so forth) that were used in JDK 1.0.2 before
the names were standardized.
C-6
C
Font Configuration
Adding a new font is a system administration function, and is
somewhat dependent upon the platform, although there is a great deal
in common between systems. This course looks at Solaris environment
and Microsoft Windows installations under the Sun JDK.
C-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
C-8
C
Adding a Font to Microsoft Windows
The ANSI_CHARSET part of this entry indicates the Win32 charset
information for the font. This should be provided with the font, but for
most fonts providing latin characters, this will usually be
ANSI_CHARSET. Another common value here is
SYMBOL_CHARSET, which usually relates to fonts containing the
WingDings characters.
Microsoft Windows font files are generally indexed using Unicode,
which simplifies the job of the Java runtime, and of installing them.
However, for those that are not, you need to append the keyword
NEED_CONVERTED to the configuration line, and add secondary
information indicating how the indices can be converted to and from
Unicode character numbers. Specify the conversion using a line like
this:
fontcharset.serif.1=sun.awt.windows.CharToByteWingDings
Note that the digit (1 in this example,) should match the digit in the
original declaration. The fully qualified classname indicates a class
(which must be available to the runtime, on CLASSPATH) that can be
used to convert the font indexes to and from Unicode values.
C-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
C-10
C
Check Your Progress
Before continuing on to the next module, check that you are able to
accomplish or answer the following:
Install new fonts, and configure font aliases for us in either Solaris
or Microsoft Windows JDK/JRE environments
C-11
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
C-12
This appendix describes the undo/redo mechanism and its use with
the JTextPane.
D-1
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
D
Relevance
Discussion Do you or the users of your programs ever make
mistakes when editing a document? Would your applications benefit
from an undo/redo feature? How difficult would this be to
implement?
D-2
D
Objectives
Upon completion of this appendix, you will be able to:
D-3
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
Undo/Redo Features
The JTextComponent, or more precisely the Document that provides
the model used by a JTextComponent, supports the idea of an
undo/redo feature. From the point of view of the Document interface,
this is a framework, and any appropriate implementation may be built
using that framework. However, for most situations, the default
implementation that is provided by the DefaultStyledDocument
will be satisfactory.
The principle of operation of the undo/redo mechanism is quite
simple. The Document interface issues an UndoableEditEvent for
each change that it performs. These are received by registered
listeners. To support listener registration in the usual way,
add/removeUndoableEditListener methods are provided by the
Document interface.
The UndoableEdit class has two key methods, undo and redo,
which should reverse or restore the edit that the event describes if
possible and appropriate.
D-4
D
Undo/Redo Features
As well as the undo and redo methods, UndoableEdit can report
its name, which might be useful in a user interface, to describe which
action is about to be reversed or restored. It can also report if it is
currently able to undo or redo using the canUndo and canRedo
methods. Finally, you can make an UndoableEditEvent destroy the
record associated with itself (to save memory) by issuing the die
method call. After a call to die both canUndo and canRedo methods
will return false permanently for that object.
If a user interface is to provide the user a means to call either undo or
redo on an UndoableEditEvent object, then there must be some
record kept of the UndoableEditEvent objects that are sent by the
Document. You could achieve this by using a java.util.Stack, or
an array, or even a java.util.Vector. A special class,
javax.swing.undo.UndoManager, is provided. This class, which
implements UndoableEditListener, may be used directly to collect
the events that the Document issues. It provides convenience
methods that readily enable you to undo or redo recent changes
(moving the event from the undo stack to the redo stack or vice versa,
as needed,) trim the undo and redo stacks, to limit the amount of
memory required, report the top stack items from both undo and redo
stacks, and more. The following example uses this class and
demonstrates its key features.
D-5
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
D
Undo Example
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4 import javax.swing.event.*;
5 import javax.swing.text.*;
6 import javax.swing.undo.*;
7
8 public class Undoer {
9
public static void main(String args[]) {
10
JFrame frame = new JFrame("Undoable Edits");
11
JTextPane pane = new JTextPane();
12
frame.getContentPane().add(pane, BorderLayout.CENTER);
13
DisplayableUndoManager undoer = new DisplayableUndoManager(pane);
14
frame.getContentPane().add(undoer, BorderLayout.SOUTH);
15
frame.pack();
16
frame.setVisible(true);
17 }
18 }
19
20 class DisplayableUndoManager extends JPanel
implements UndoableEditListener {
21 private UndoManager undoManager = new UndoManager();
22 private JTextField nextUndo = new JTextField("", 30);
23 private JTextField nextRedo = new JTextField("", 30);
24 private JButton undoButton = new JButton("Undo");
25 private JButton redoButton = new JButton("Redo");
26 private JPanel leftPanel = new JPanel();
27 private JPanel rightPanel = new JPanel();
28
29 public DisplayableUndoManager(JTextComponent editSource) {
30
leftPanel.setLayout(new GridLayout(2, 1));
31
leftPanel.add(undoButton);
32
leftPanel.add(redoButton);
33
34
rightPanel.setLayout(new GridLayout(2, 1));
35
rightPanel.add(nextUndo);
36
rightPanel.add(nextRedo);
37
D-6
D
Undo Example
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 }
setLayout(new BorderLayout());
add(leftPanel, BorderLayout.WEST);
add(rightPanel, BorderLayout.CENTER);
nextUndo.setEnabled(false); // just for viewing.
nextRedo.setEnabled(false); // ditto
editSource.getDocument().addUndoableEditListener(this);
undoButton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent ev) {
undoManager.undo();
refresh();
}
}
);
redoButton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent ev) {
undoManager.redo();
refresh();
}
}
);
}
public void undoableEditHappened(UndoableEditEvent ev) {
undoManager.undoableEditHappened(ev);
refresh();
}
private void refresh() {
nextUndo.setText(undoManager.getUndoPresentationName());
nextRedo.setText(undoManager.getRedoPresentationName());
undoButton.setEnabled(undoManager.canUndo());
redoButton.setEnabled(undoManager.canRedo());
}
D-7
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
D
Undo Example
This example seeks to demonstrate that implementing the undo/redo
feature using the UndoManager and default Document
implementations is really quite easy. There are a number of aspects of
this example that are described here.
The DisplayableUndoManager class simply defines a user interface
(a view-controller, in fact) for the standard UndoManager (which
constitutes a model in the MVC sense) The user interface displays the
top of the undo and redo stacks, showing the name of the
UndoableEditEvent in each case. If the event can be undone or
redone, according to context, then the undo or redo button is enabled,
otherwise it is disabled and will appear grayed out. Every time a
new event comes in, or when an undo or redo action is invoked, the
refresh method ensures that this information is up to date.
The method undoableEditHappened is used to implement the
UndoableEditEvent interface. Notice that the
DisplayableUndoManager class must extend some
java.awt.Component in order to be displayable; therefore it cannot
simultaneously extend the UndoManager. Instead, it must contain an
instance of UndoManager, and implement the interface itself, passing
the calls into the UndoManager as necessary.
The undo and redo buttons (referred to by variables undoButton and
redoButton respectively) have action event handlers that simply
proxy into calling the UndoManager undo and redo methods.
These methods will never be invoked improperly since the refresh
method ensures that the buttons are disabled if it is inappropriate to
call their action routines.
Notice that the real work is all done in the UndoManager instance that
is created within this example. UndoableEditEvent objects are
passed to that from the Document, and the undo and redo methods
work as expected, with the simple proviso that they are only called if
the UndoManager reports canUndo or canRedo as true respectively.
D-8
D
Check Your Progress
Before continuing on to the next appendix, check that you are able to
accomplish or answer the following:
D-9
Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. Enterprise Services November 1998, Revision A
D-10