- 1.SHER SINGH BARDHANsWhat is Swing?To create a Java program
with a graphical user interface (GUI), youll want to learn about
Swing.The Swing toolkit includes a rich set of components for
building GUIs and adding interactivityto Java applications. Swing
includes all the components you would expect from a moderntoolkit:
table controls, list controls, tree controls, buttons, and
labels.Swing is far from a simple component toolkit, however. It
includes rich undo support, a highlycustomizable text package,
integrated internationalization and accessibility support. To
trulyleverage the cross-platform capabilities of the Java platform,
Swing supports numerous look andfeels, including the ability to
create your own look and feel. The ability to create a custom
lookand feel is made easier with Synth, a look and feel
specifically designed to be customized. Swingwouldnt be a component
toolkit without the basic user interface primitives such as drag
anddrop, event handling, customizable painting, and window
management.Swing is part of the Java Foundation Classes (JFC). The
JFC also include other featuresimportant to a GUI program, such as
the ability to add rich graphics functionality and the abilityto
create a program that can work in different languages and by users
with different inputdevices.The following list shows some of the
features that Swing and the Java Foundation Classesprovide.Swing
GUI Components The Swing toolkit includes a rich array of
components: from basic components, such as buttons and check boxes,
to rich and complex components, such as tables and text. Even
deceptively simple components, such as text fields, offer
sophisticated functionality, such as formatted text input or
password field behavior. There are file browsers and dialogs to
suit most needs, and if not, customization is possible. If none of
Swings provided components are exactly what you need, you can
leverage the basic Swing component functionality to create your
own.Java 2D API To make your application stand out; convey
information visually; or add figures, images, or animation to your
GUI, youll want to use the Java 2D API. Because Swing is built on
the 2D package, its trivial to make use of 2D within Swing
components. Adding images, drop shadows, compositing its easy with
Java 2D.Pluggable Look-and-Feel Support Any program that uses Swing
components has a choice of look and feel. The JFC classes shipped
by Sun and Apple provide a look and feel that matches that of the
platform. The
2. SHER SINGH BARDHANs Synth package allows you to create your
own look and feel. The GTK+ look and feel makes hundreds of
existing look and feels available to Swing programs. A program can
specify the look and feel of the platform it is running on, or it
can specify to always use the Java look and feel, and without
recompiling, it will just work. Or, you can ignore the issue and
let the UI manager sort it out.Data Transfer Data transfer, via
cut, copy, paste, and drag and drop, is essential to almost any
application. Support for data transfer is built into Swing and
works between Swing components within an application, between Java
applications, and between Java and native
applications.Internationalization This feature allows developers to
build applications that can interact with users worldwide in their
own languages and cultural conventions. Applications can be created
that accept input in languages that use thousands of different
characters, such as Japanese, Chinese, or Korean. Swings layout
managers make it easy to honor a particular orientation required by
the UI. For example, the UI will appear right to left in a locale
where the text flows right to left. This support is automatic: You
need only code the UI once and then it will work for left to right
and right to left, as well as honor the appropriate size of
components that change as you localize the text.Accessibility API
People with disabilities use special software assistive
technologies that mediates the user experience for them. Such
software needs to obtain a wealth of information about the running
application in order to represent it in alternate media: for a
screen reader to read the screen with synthetic speech or render it
via a Braille display, for a screen magnifier to track the caret
and keyboard focus, for on-screen keyboards to present dynamic
keyboards of the menu choices and toolbar items and dialog
controls, and for voice control systems to know what the user can
control with his or her voice. The accessibility API enables these
assistive technologies to get the information they need, and to
programmatically manipulate the elements that make up the graphical
user interface.Undo Framework API Swings undo framework allows
developers to provide support for undo and redo. Undo support is
built in to Swings text component. For other components, Swing
supports an unlimited number of actions to undo and redo, and is
easily adapted to an application. For example, you could easily
enable undo to add and remove elements from a table. 3. SHER SINGH
BARDHANsFlexible Deployment Support If you want your program to run
within a browser window, you can create it as an applet and run it
using Java Plug-in, which supports a variety of browsers, such as
Internet Explorer, Firefox, and Safari. If you want to create a
program that can be launched from a browser, you can do this with
Java Web Start. Of course, your application can also run outside of
browser as a standard desktop application. For more information on
deploying an application, see the deployment trail in this
tutorial.This trail provides an overview of Swing capabilities,
beginning with a demo that showcasesmany of these features. When
you are ready to begin coding, the Creating GUI with JFC/Swingtrail
provides the programming techniques to take advantage of these
featuresA Swing DemoHere is an example of an application,
PasswordStore, that illustrates some of Swings rich featureset.
PasswordStore allows the user to manage login information for
various hosts. It alsogenerates passwords, evaluates the
effectiveness of a password, and allows you to store notesabout a
particular host or assign an icon to represent the host.Click the
launch button to run PasswordStore using Java Web Start. [Requires
release 6.0.]The following highlights some of the specific features
of the PasswordStore application:Host Info At program launch, the
list of hosts is displayed in a Swing list component. Using the
View menu, the view can be toggled between the table and the list.
In both views, the Host/Account Filter text field can be used to
dynamically restrict the entries to those where the host or account
name contains the typed string.List View The Swing list component
can be customized to include visual data. As shown in the following
figure, an optional miniature icon to the left of the host name
represents the host. The graphic to the right uses color and
proportional fill to reflect the strength of the password (Red =
poor, yellow = fair, green = good). The bar changes dynamically as
the user enters/modifies the password in the text field below. The
user has typed the text "oo" in the filter text field, which
matches two entries: Heirloom Seeds and Pacific Zoo Shop. 4. SHER
SINGH BARDHANs Host Info (List View) and Filter Text FieldTable
ViewThe Swing table component allows the user to rearrange the
columns by dragging thecolumn header. Also, a column can be sorted
by clicking the column header. If thecolumn you click on isnt
highlighted as the primary sorted column, it will become theprimary
sorted column in ascending order. Clicking on the primary sorted
column togglesthe sort order. For example, if column 1 isnt
selected, clicking on it will make it theselected column and the
data is sorted in ascending order. Clicking column 1 again willsort
the data in descending order. Clicking on column 2 will make column
2 the primarycolumn in ascending order. 5. SHER SINGH BARDHANs Host
Info (Table View)Details/Notes Tabbed PaneThe tabbed pane below the
host info allows the user to choose between the Details paneland
the Notes text pane, keeping the overall footprint of the window
smaller and lessoverwhelming.Details PanelThe icon area on the left
can be assigned an image by either dragging an image (jpg, png,gif,
or tif) to the area or by clicking the image well and bringing up a
file browser.The text fields (used to enter or modify the host
name, login, and password) supportcut/copy, paste, drag, drop,
undo, and redo.As the user enters or modifies the password, the 2D
bar chart dynamically displays thedistribution of the password. If
the list view is currently displayed, the correspondingcolored bar
in the list also changes dynamically. 6. SHER SINGH BARDHANsNotes
Text PaneThis is the text component where the user can save notes
about the selected host. If thetext pane contains a URI, Swings
text component provides the ability to click on the URIand a
browser window automatically opens to that location.Wizzy 2D
GraphicsPasswordStore uses customized graphics in several ways to
enhance the UI: In the listview, images are used to represent each
host; a colored bar, the Strength Visualizer,represents the
effectiveness of a password; and a dynamic bar chart, the
PasswordVisualizer, displays the distribution of a password. When
you add an image, whether bydragging and dropping it into the image
well (in the Details panel) or by clicking the welland bringing up
the file browser, a mini-icon is automatically generated for the
list view.Note: This demo is meant to be illustrative only and not
meant to be used for realanalysis of passwords. 7. SHER SINGH
BARDHANs 2D Graphics UsedMultiple Look and Feels This provides the
ability to switch between three look and feels using the View menu:
Java (called Metal), Motif/CDE, and the native look and feel:
Windows on Microsoft Windows, Aqua on Mac OS X, and so on.Undo and
Redo Undo and redo works on text, as you would expect, but it also
works on actions. For example, you can generate a password using
the Account > Generate Password menu, and if you dont like the
new password you can undo it using Edit > Undo or the control- Z
shortcut. Similarly, you can redo the undo using Edit > Redo, or
the control-Y shortcut.The PasswordStore demo has a reasonable
level of complexity for a small Swing application andshows a
sampling of Swings capabilities. The Source Code is available for
download, but it isoutside the scope of this chapter to discuss the
implementation in detail.NOTE: If PasswordStore were a production
application, it would most likely encrypt thepassword database;
however, due to legal restrictions on distributing information of
that nature,it is not included here.A Visual Guide to Swing
Components (JavaLook and Feel)This page shows Swing components in
the Java look and feel. The following page shows thesame components
in the Windows look and feel.Basic ControlsSimple components that
are used primarily to get input from the user; they may also show
simplestate.JButton 8. SHER SINGH
BARDHANsJCheckBoxJComboBoxJListJMenu 9. SHER SINGH
BARDHANsJRadioButtonJSliderJSpinnerJTextFieldJPasswordFieldInteractive
Displays of Highly Formatted InformationThese components display
highly formatted information that (if you choose) can be modified
bythe user. 10. SHER SINGH BARDHANsJColorChooserJEditorPane and
JTextPane 11. SHER SINGH BARDHANsJFileChooserJTableJTextAreaJTree
12. SHER SINGH BARDHANsUneditable Information DisplaysThese
components exist solely to give the user
information.JLabelJProgressBarJSeparatorJToolTipTop-Level
ContainersAt least one of these components must be present in any
Swing application.JApplet 13. SHER SINGH
BARDHANsJDialogJFrameGeneral-Purpose ContainersThese
general-purpose containers are used in most Swing
applications.JPanelJScrollPane 14. SHER SINGH
BARDHANsJSplitPaneJTabbedPaneJToolBarSpecial-Purpose
ContainersThese special-purpose containers play specific roles in
the UI.JInternalFrame 15. SHER SINGH BARDHANsJLayeredPaneRoot
panePluggable Look and FeelThe Swing toolkit allows you to decide
how to configure the particular look and feel of your
application.If you dont specify a look and feel, the Swing UI
manager figures out which one to use. The options forsetting a look
and feel include: Leave it up to the Swing UI manager. If a
particular look and feel is not specified by the program,Swings UI
manager checks whether the user has specified a preference. If that
preferencehasnt been specified or isnt available, the default look
and feel is used. The default look andfeel is determined by the
supplier of the JRE. For the JRE that Sun provides, the Java look
andfeel (called Metal) is used. The Java look and feel works on all
platforms. Use the look and feel of the native platform. If the
application is running on a MicrosoftWindows XP machine, the
Windows look and feel is used. On Mac OS platforms, the Aqua
lookand feel is used. On UNIX platforms, such as Solaris or Linux,
either the GTK+ look and feel or theCDE/Motif look and feel is
used, depending on the users desktop choice. 16. SHER SINGH
BARDHANs Specify a particular look and feel. Swing ships with four
look and feels: Java (also called Metal), Microsoft Windows, GTK+,
and CDE/Motif. The GTK+ look and feel requires a theme, and there
are many available for free on the Internet. Create your own look
and feel using the Synth package. Use an externally provided look
and feel.As shown in the following figures, PasswordStore offers a
choice of three look and feels. TheAlloy look and feel has been
provided courtesy of Incors. Java look and feel 17. SHER SINGH
BARDHANsWindows look and feel 18. SHER SINGH BARDHANsCDE/Motif look
and feel 19. SHER SINGH BARDHANs Default Alloy look and feelData
TransferThe Swing toolkit supports the ability to transfer data
between components within the same Javaapplication, between
different Java applications, and between Java and native
applications. Datacan be transferred via a drag and drop gesture,
or via the clipboard using cut, copy, and paste.Drag and
DropDrag-and-drop support can be easily enabled for many of Swings
components (sometimes with asingle line of code). For example, its
trivial to enable drag and drop and copy and paste supportfor
JTable, Swings table component. All you need to provide is the data
representing theselection and how to get your data from the
clipboard thats it! 20. SHER SINGH BARDHANsCut, Copy, and PasteMost
of the text-based components, such as editor pane and text field,
support cut/copy and pasteout of the box. Of course, menu items
need to be created and "wired up" to the appropriateactions. Other
components, such as list and tree, can support cut, copy, and paste
with someminimal work.PasswordStore supports data transfer in a
variety of ways: The text in both the list and the table view
supports cut, copy, and paste. The text fields in the Details
Panel, the Filter text field, and the Notes text pane
supportcut/copy, paste, and drag and drop. The Company icon region
in the Details panel accepts a dropped image (jpg, png, gif, or
tif).Internationalization and LocalizationInternationalization is
the process of designing an application so that the user can run it
using his or hercultural preferences without modifying or
recompiling the code. These cultural preferences, collectivelyknown
as locale, include (but arent limited to): language, currency
formatting, time and dateformatting, and numeric formatting.An
internationalized program is designed so that text elements, such
as status messages and GUIcomponent labels, are stored outside the
source code in resource bundles and retrieveddynamically.
Separating the locale-specific information from the code is what
allows a programto run in different languages and with different
preferences without having to recompile.Localization is the process
of translating the text to a particular language and adding any
locale-specific components. When an application is localized to a
language and you run the app in thatlocale, Swing grabs the
localized strings from the resource bundle and the layout manager
resizesthe component accordingly.For example, an English-speaking
person writes an application following the rules
ofinternationalization; later, that application is localized to
Japanese and Spanish. When a userwith the Language System
Preference set to Japanese runs the application, Swing detects
this.When the application appears, the menus, labels, buttons, and
so on, show Japanese text, and thecomponents are scaled
accordingly. If that user then quits the program, sets the language
systempreference to Spanish, and re-launches the application, the
application appears in Spanish, scaledaccording to the new
character set.Swings layout managers understand how locale affects
a UI it is not necessary to create anew layout for each locale. For
example, in a locale where text flows right to left, the
layoutmanager will arrange components in the same orientation, if
specified. Bidi text (mixeddirectional text, used by Hebrew and
Arabic, for example) is supported as well. 21. SHER SINGH
BARDHANsEvery program should be designed with internationalization
in mind: GUI component labels,status messages, currency, date,
phone, and address formats should not be hardcoded intoprograms.
Once a program has been internationalized, a language expert can
perform the actualtranslation at a later date without requiring any
recompiling.As the following screenshots show, PasswordStore has
been localized to Japanese and Arabic.PasswordStore in Japanese 22.
SHER SINGH BARDHANs PasswordStore in ArabicAccessibilityAssistive
technologies exist to enable people with permanent or temporary
disabilities to use thecomputer. This includes a wide variety of
techniques and equipment voice interfaces, magnifiers,screen
readers, closed captioning, keyboard enhancements, and so on. In
many countries, including theUnited States, Australia, Canada, and
the European Union, there are laws requiring that programsfunction
smoothly with assistive technologies. For more information, see
Oracles Accessibility Program.A certain level of accessibility is
built-in to all Swing components, but full accessibility can
beachieved by following some simple rules. For example, assign tool
tips, keyboard alternatives,and textual descriptions for images,
wherever possible.The PasswordStore demo follows the rules set out
for accessibility. In the following figure, youcan see an example
of tool tip text. 23. SHER SINGH BARDHANsPasswordStore With a
TooltipFor more information, see How to Support Assistive
Technologies.Integrating with the DesktopThe Desktop API,
introduced in version 6 of the Java Platform, Standard Edition
(Java SE),enables Java applications to integrate seamlessly with
the desktop. Three types of integration aresupported: The ability
to launch the host systems default browser with a specific Uniform
Resource Identifier (URI). The ability to launch the host systems
default email client. The ability to launch applications to open,
edit, or print files associated with those applications. 24. SHER
SINGH BARDHANsYou can see this in the PasswordStore demo in the
Notes text pane. Click on the link that isdisplayed in the text
pane it opens the specified URI in the default browser. Click on
the URI and it opens in the Default BrowserSystem Tray Icon
SupportThe desktop of some platforms, such as Microsoft Windows,
includes a system tray, as shown in thefollowing screenshot:On
Microsoft Windows, it is called the "Taskbar Status Area." On
Gnome, the "NotificationArea", and on KDE, the "System Tray."
However it may be called, the system tray is shared byall
applications. 25. SHER SINGH BARDHANsOn platforms where it is
supported, an application may insert a mini-icon, called a Tray
Icon,into the system tray. This icon can be used to notify the user
of a change in the applicationsstatus, or a need to take a
particular action. Clicking the tray icon can bring up the
applicationwindow. A popup menu and a tooltip can also be attached
to the tray icon.System traysupport was added in version 6 of Java
SE. For more information, see the NewSystem Tray Functionality in
Java SE 6 article.About the JFC and SwingJFC is short for Java
Foundation Classes, which encompass a group of features for
building graphical userinterfaces (GUIs) and adding rich graphics
functionality and interactivity to Java applications. It is
definedas containing the features shown in the table below.
FeatureDescriptionIncludes everything from buttons to split panes
to tables. Many components areSwing GUIcapable of sorting,
printing, and drag and drop, to name a few of the
supportedComponentsfeatures.The look and feel of Swing applications
is pluggable, allowing a choice of look andfeel. For example, the
same program can use either the Java or the Windows lookPluggable
Look-and-and feel. Additionally, the Java platform supports the
GTK+ look and feel, whichFeel Supportmakes hundreds of existing
look and feels available to Swing programs. Manymore look-and-feel
packages are available from various sources.Enables assistive
technologies, such as screen readers and Braille displays, to
getAccessibility APIinformation from the user interface.Enables
developers to easily incorporate high-quality 2D graphics, text,
andJava 2D API images in applications and applets. Java 2D includes
extensive APIs for generatingand sending high-quality output to
printing devices.Allows developers to build applications that can
interact with users worldwide intheir own languages and cultural
conventions. With the input method
frameworkInternationalizationdevelopers can build applications that
accept text in languages that usethousands of different characters,
such as Japanese, Chinese, or Korean.This trail concentrates on the
Swing components. We help you choose the appropriatecomponents for
your GUI, tell you how to use them, and give you the background
informationyou need to use them effectively. We also discuss other
JFC features as they apply to Swingcomponents. 26. SHER SINGH
BARDHANsWhich Swing Packages Should I Use?The Swing API is
powerful, flexible and immense. The Swing API has 18 public
packages:javax.accessibilityjavax.swing.plaf
javax.swing.textjavax.swingjavax.swing.plaf.basic
javax.swing.text.htmljavax.swing.border javax.swing.plaf.metal
javax.swing.text.html.parserjavax.swing.colorchooser
javax.swing.plaf.multi
javax.swing.text.rtfjavax.swing.eventjavax.swing.plaf.synth
javax.swing.treejavax.swing.filechooserjavax.swing.tablejavax.swing.undoFortunately,
most programs use only a small subset of the API. This trail sorts
out the API foryou, giving you examples of common code and pointing
you to methods and classes youre likelyto need. Most of the code in
this trail uses only one or two Swing packages: javax.swing
javax.swing.event (not always required)Lesson: Learning Swing with
the NetBeansIDE Examples IndexThis lesson provides an introduction
to Graphical User Interface (GUI) programming with Swingand the
NetBeans IDE. As you learned in the "Hello World!" lesson, the
NetBeans IDE is a free,open-source, cross-platform integrated
development environment with built-in support for theJava
programming language. It offers many advantages over coding with a
text editor; werecommend its use whenever possible. If you have not
yet read the above lesson, please take amoment to do so now. It
provides valuable information about downloading and installing
theJDK and NetBeans IDE.The goal of this lesson is to introduce the
Swing API by designing a simple application thatconverts
temperature from Celsius to Fahrenheit. Its GUI will be basic,
focusing on only a subsetof the available Swing components. We will
use the NetBeans IDE GUI builder, which makesuser interface
creation a simple matter of drag and drop. Its automatic code
generation featuresimplifies the GUI development process, letting
you focus on the application logic instead of theunderlying
infrastructure. 27. SHER SINGH BARDHANsBecause this lesson is a
step-by-step checklist of specific actions to take, we recommend
that yourun the NetBeans IDE and perform each step as you read
along. This will be the quickest andeasiest way to begin
programming with Swing. If you are unable to do so, simply reading
alongshould still be useful, since each step is illustrated with
screenshots.If you prefer the traditional approach of programming
each component manually (without theassistance of an IDE), think of
this lesson as an entry point into the lower-level
discussionsalready provided elsewhere in the tutorial. Hyperlinks
in each discussion will take you to relatedlessons, should you wish
to learn such lower-level details.The finished GUI for this
application will look as follows:The CelsiusConverter
Application.Click the Launch button to run CelsiusConverter using
JDK 1.7 Alternatively, to compile and run theexample yourself,
consult theFrom an end-users perspective, usage is simple: enter a
temperature (in Celsius) into the textbox, click the "Convert"
button, and watch the converted temperature (in Fahrenheit) appear
onscreen. The minimize, maximize, and close buttons will behave as
expected, and the applicationwill also have a title that appears
along the top of the window.From a programmers perspective, we will
write the application in two main stages. First, we willpopulate
the GUI with the various Swing components and arrange them as shown
above. Then,we will add the application logic, so that the program
actually performs a conversion when theuser presses the "Convert"
button.Setting up the CelsiusConverter ProjectIf you have worked
with the NetBeans IDE in the past, much of this section will look
familiar, since theinitial steps are similar for most projects.
Still, the following steps describe settings that are specific
tothis application, so take care to follow them closely.Step 1:
Create a New ProjectTo create a new project, launch the NetBeans
IDE and choose New Project from the File menu: 28. SHER SINGH
BARDHANs Creating a New ProjectKeyboard shortcuts for each command
appear on the far right of each menu item. The look and feel ofthe
NetBeans IDE may vary across platforms, but the functionality will
remain the same.Step 2: Choose General -> Java ApplicationNext,
select General from the Categories column, and Java Application
from the Projects column:This figure has been reduced to fit on the
page.Click the image to view it at its natural size. 29. SHER SINGH
BARDHANsYou may notice mention of "J2SE" in the description pane;
that is the old name for what is nowknown as the "Java SE"
platform. Press the button labeled "Next" to proceed.Step 3: Set a
Project NameNow enter "CelsiusConverterProject" as the project
name. You can leave the Project Locationand Project Folder fields
set to their default values, or click the Browse button to choose
analternate location on your system.This figure has been reduced to
fit on the page.Click the image to view it at its natural size.Make
sure to deselect the "Create Main Class" checkbox; leaving this
option selected generates anew class as the main entry point for
the application, but our main GUI window (created in thenext step)
will serve that purpose, so checking this box is not necessary.
Click the "Finish"button when you are done. 30. SHER SINGH
BARDHANsThis figure has been reduced to fit on the page.Click the
image to view it at its natural size.When the IDE finishes loading,
you will see a screen similar to the above. All panes will beempty
except for the Projects pane in the upper left hand corner, which
shows the newly createdproject.Step 4: Add a JFrame FormThis figure
has been reduced to fit on the page.Click the image to view it at
its natural size.Now right-click the CelsiusConverterProject name
and choose New -> JFrame Form (JFrame isthe Swing class
responsible for the main frame for your application.) You will
learn how todesignate this class as the applications entry point
later in this lesson. 31. SHER SINGH BARDHANsStep 5: Name the GUI
ClassNext, type CelsiusConverterGUI as the class name, and learn as
the package name. You canactually name this package anything you
want, but here we are following the tutorial convention ofnaming
the package after the lesson in which is resides.This figure has
been reduced to fit on the page.Click the image to view it at its
natural size.The remainder of the fields should automatically be
filled in, as shown above. Click the Finishbutton when you are
done.This figure has been reduced to fit on the page.Click the
image to view it at its natural size. 32. SHER SINGH BARDHANsWhen
the IDE finishes loading, the right pane will display a
design-time, graphical view of theCelsiusConverterGUI. It is on
this screen that you will visually drag, drop, and manipulate
thevarious Swing components.Using Top-Level ContainersAs we
mentioned before, Swing provides three generally useful top-level
container classes: JFrame,JDialog, and JApplet. When using these
classes, you should keep these facts in mind: To appear onscreen,
every GUI component must be part of a containment hierarchy. A
containment hierarchy is a tree of components that has a top-level
container as its root. Well show you one in a bit. Each GUI
component can be contained only once. If a component is already in
a container and you try to add it to another container, the
component will be removed from the first container and then added
to the second. Each top-level container has a content pane that,
generally speaking, contains (directly or indirectly) the visible
components in that top-level containers GUI. You can optionally add
a menu bar to a top-level container. The menu bar is by convention
positioned within the top-level container, but outside the content
pane. Some look and feels, such as the Mac OS look and feel, give
you the option of placing the menu bar in another place more
appropriate for the look and feel, such as at the top of the
screen.Note: Although JInternalFrame mimics JFrame, internal frames
arent actually top-level containers.Heres a picture of a frame
created by an application. The frame contains a green menu bar
(with nomenus) and, in the frames content pane, a large blank,
yellow label. 33. SHER SINGH BARDHANsYou can find the entire source
for this example in TopLevelDemo.java. Although the exampleuses a
JFrame in a standalone application, the same concepts apply to
JApplets and JDialogs.Heres the containment hierarchy for this
examples GUI:As the ellipses imply, we left some details out of
this diagram. We reveal the missing details a bitlater. Here are
the topics this section discusses: Top-Level Containers and
Containment Hierarchies Adding Components to the Content Pane
Adding a Menu Bar The Root Pane (a.k.a. The Missing
Details)Top-Level Containers and Containment HierarchiesEach
program that uses Swing components has at least one top-level
container. This top-level containeris the root of a containment
hierarchy the hierarchy that contains all of the Swing components
thatappear inside the top-level container.As a rule, a standalone
application with a Swing-based GUI has at least one
containmenthierarchy with a JFrame as its root. For example, if an
application has one main window and twodialogs, then the
application has three containment hierarchies, and thus three
top-levelcontainers. One containment hierarchy has a JFrame as its
root, and each of the other two has aJDialog object as its root.A
Swing-based applet has at least one containment hierarchy, exactly
one of which is rooted by aJApplet object. For example, an applet
that brings up a dialog has two containment hierarchies.The
components in the browser window are in a containment hierarchy
rooted by a JAppletobject. The dialog has a containment hierarchy
rooted by a JDialog object.Adding Components to the Content
PaneHeres the code that the preceding example uses to get a frames
content pane and add the yellow labelto
it:frame.getContentPane().add(yellowLabel, BorderLayout.CENTER);
34. SHER SINGH BARDHANsAs the code shows, you find the content pane
of a top-level container by calling the getContentPanemethod. The
default content pane is a simple intermediate container that
inherits from JComponent,and that uses a BorderLayout as its layout
manager.Its easy to customize the content pane setting the layout
manager or adding a border, forexample. However, there is one tiny
gotcha. The getContentPane method returns a Containerobject, not a
JComponent object. This means that if you want to take advantage of
the contentpanes JComponent features, you need to either typecast
the return value or create your owncomponent to be the content
pane. Our examples generally take the second approach, since its
alittle cleaner. Another approach we sometimes take is to simply
add a customized component tothe content pane, covering the content
pane completely.Note that the default layout manager for JPanel is
FlowLayout; youll probably want to changeit.To make a component the
content pane, use the top-level containers setContentPane
method.For example://Create a panel and add components to it.JPanel
contentPane = new JPanel(new
BorderLayout());contentPane.setBorder(someBorder);contentPane.add(someComponent,
BorderLayout.CENTER);contentPane.add(anotherComponent,
BorderLayout.PAGE_END);topLevelContainer.setContentPane(contentPane);Note:
As a convenience, the add method and its variants, remove and
setLayout have beenoverridden to forward to the contentPane as
necessary. This means you can writeframe.add(child);and the child
will be added to the contentPane.Note that only these three methods
do this. This means that getLayout() will not return the layoutset
with setLayout().Adding a Menu BarIn theory, all top-level
containers can hold a menu bar. In practice, however, menu bars
usually appearonly in frames and applets. To add a menu bar to a
top-level container, create a JMenuBar object,populate it with
menus, and then call setJMenuBar. The TopLevelDemo adds a menu bar
to its framewith this code:frame.setJMenuBar(greenMenuBar);For more
information about implementing menus and menu bars, see How to Use
Menus. 35. SHER SINGH BARDHANsThe Root PaneEach top-level container
relies on a reclusive intermediate container called the root pane.
The root panemanages the content pane and the menu bar, along with
a couple of other containers. You generallydont need to know about
root panes to use Swing components. However, if you ever need to
interceptmouse clicks or paint over multiple components, you should
get acquainted with root panes.Heres a list of the components that
a root pane provides to a frame (and to every other
top-levelcontainer):Weve already told you about the content pane
and the optional menu bar. The two other componentsthat a root pane
adds are a layered pane and a glass pane. The layered pane contains
the menu bar andcontent pane, and enables Z-ordering of other
components. The glass pane is often used to interceptinput events
occuring over the top-level container, and can also be used to
paint over multiplecomponents.For more details, see How to Use Root
Panes.The JComponent ClassWith the exception of top-level
containers, all Swing components whose names begin with "J"
descendfrom the JComponent class. For example, JPanel, JScrollPane,
JButton, and JTable all inheritfrom JComponent. However, JFrame and
JDialog dont because they implement top-levelcontainers.The
JComponent class extends the Container class, which itself extends
Component. TheComponent class includes everything from providing
layout hints to supporting painting andevents. The Container class
has support for adding components to the container and layingthem
out. This sections API tables summarize the most often used methods
of Component andContainer, as well as of JComponent.JComponent
FeaturesThe JComponent class provides the following functionality
to its descendants: 36. SHER SINGH BARDHANs Tool tips Painting and
borders Application-wide pluggable look and feel Custom properties
Support for layout Support for accessibility Support for drag and
drop Double buffering Key bindingsTool tipsBy specifying a string
with the setToolTipText method, you can provide help to users of
acomponent. When the cursor pauses over the component, the
specified string is displayed in asmall window that appears near
the component. See How to Use Tool Tips for
moreinformation.Painting and borders The setBorder method allows
you to specify the border that a component displays around its
edges. To paint the inside of a component, override the
paintComponent method. See How to Use Borders and Performing Custom
Painting for details.Application-wide pluggable look and feel
Behind the scenes, each JComponent object has a corresponding
ComponentUI object that performs all the drawing, event handling,
size determination, and so on for that JComponent. Exactly which
ComponentUI object is used depends on the current look and feel,
which you can set using the UIManager.setLookAndFeel method. See
How to Set the Look and Feel for details.Custom properties You can
associate one or more properties (name/object pairs) with any
JComponent. For example, a layout manager might use properties to
associate a constraints object with each JComponent it manages. You
put and get properties using the putClientProperty and
getClientProperty methods. For general information about
properties, see Properties.Support for layout Although the
Component class provides layout hint methods such as
getPreferredSize and getAlignmentX, it doesnt provide any way to
set these layout hints, short of creating a subclass and overriding
the methods. To give you another way to set layout hints, the
JComponent class adds setter methods setMinimumSize,
setMaximumSize, setAlignmentX, and setAlignmentY. See Laying Out
Components Within a Container for more information. 37. SHER SINGH
BARDHANsSupport for accessibilityThe JComponent class provides API
and basic functionality to help assistive technologies suchas
screen readers get information from Swing components, For more
information aboutaccessibility, see How to Support Assistive
Technologies.Support for drag and dropThe JComponent class provides
API to set a components transfer handler, which is the basis
forSwings drag and drop support. See Introduction to DnD for
details.Double bufferingDouble buffering smooths on-screen
painting. For details, see Performing Custom Painting.Key
bindingsThis feature makes components react when the user presses a
key on the keyboard. Forexample, in many look and feels when a
button has the focus, typing the Space key is equivalentto a mouse
click on the button. The look and feel automatically sets up the
bindings betweenpressing and releasing the Space key and the
resulting effects on the button. For moreinformation about key
bindings, see How to Use Key Bindings.The JComponent APIThe
JComponent class provides many new methods and inherits many
methods from Component andContainer. The following tables summarize
the methods we use the most. Customizing Component Appearance
Setting and Getting Component State Handling Events Painting
Components Dealing with the Containment Hierarchy Laying Out
Components Getting Size and Position Information Specifying
Absolute Size and Position Customizing Component AppearanceMethod
PurposevoidSet or get the border of the component. See How to Use
Borders for details.setBorder(Border)Border getBorder()voidSet the
foreground or background color for the component. The foreground is
38. SHER SINGH BARDHANssetForeground(Color) generally the color
used to draw the text in a component. The background isvoid (not
surprisingly) the color of the background areas of the component,
assumingsetBackground(Color) that the component is opaque.Color
getForeground() Get the foreground or background color for the
component.Color getBackground()void Set or get whether the
component is opaque. An opaque component fills
itssetOpaque(boolean) background with its background color.boolean
isOpaque()void setFont(Font) Set or get the components font. If a
font has not been set for the component,Font getFont() the font of
its parent is returned.void setCursor(Cursor) Set or get the cursor
displayed over the component and all components itCursor
getCursor() contains (except for children that have their own
cursor set). Example: aPanel.setCursor( Cursor.getPredefinedCursor(
Cursor.WAIT_CURSOR));Setting and Getting Component State
MethodPurposevoidSets the JPopupMenu for this JComponent. The UI
issetComponentPopupMenu(JPopupMenu) responsible for registering
bindings and adding thenecessary listeners such that the JPopupMenu
will be shownat the appropriate time. When the JPopupMenu is
showndepends upon the look and feel: some may show it on amouse
event, some may enable a key binding.If popup is null, and
getInheritsPopupMenu returnstrue, then getComponentPopupMenu will
be delegated tothe parent. This provides for a way to make all
childcomponents inherit the popupmenu of the parent.void
setTransferHandler(TransferHandler) Set or remove the
transferHandler property. TheTransferHandler getTransferHandler()
TransferHandler supports exchanging data via cut, copy, or paste
to/from a clipboard as well a drag and drop. See Introduction to
DnD for more details.void setToolTipText(String) Set the text to
display in a tool tip. See How to Use Tool Tips 39. SHER SINGH
BARDHANs for more information.void setName(String) Set or get the
name of the component. This can be usefulString getName() when you
need to associate text with a component that does not display
text.boolean isShowing()Determine whether the component is showing
on screen. This means that the component must be visible, and it
must be in a container that is visible and showing.void
setEnabled(boolean) Set or get whether the component is enabled. An
enabledboolean isEnabled()component can respond to user input and
generate events.void setVisible(boolean) Set or get whether the
component is visible. Componentsboolean isVisible()are initially
visible, with the exception of top-level components. Handling
Events(see Writing Event Listeners for details) MethodPurposevoid
addHierarchyListener(hierarchyListener l) Adds or removes the
specified hierarchy listenervoid
removeHierarchyListener(hierarchyListener l)to receive hierarchy
changed events from this component when the hierarchy to which this
container belongs changes. If listener l is null, no exception is
thrown and no action is performed.void
addMouseListener(MouseListener) Add or remove a mouse listener to
or from thevoid removeMouseListener(MouseListener)component. Mouse
listeners are notified when the user uses the mouse to interact
with the listened-to component.void Add or remove a mouse motion
listener to oraddMouseMotionListener(MouseMotionListener)from the
component. Mouse motion listenersvoid are notified when the user
moves the mouseremoveMouseMotionListener(MouseMotionListener)
within the listened-to components bounds.void
addKeyListener(KeyListener) Add or remove a key listener to or from
thevoid removeKeyListener(KeyListener)component. Key listeners are
notified when the user types at the keyboard and the listened-to
40. SHER SINGH BARDHANs component has the keyboard focus.void
addComponentListener(ComponentListener)Add or remove a component
listener to or fromvoid removeComponentListener(ComponentListener)
the component. Component listeners arenotified when the listened-to
component ishidden, shown, moved, or resized.boolean contains(int,
int) Determine whether the specified point is withinboolean
contains(Point)the component. The argument should be specified in
terms of the components coordinate system. The two int arguments
specify x and y coordinates, respectively.Component
getComponentAt(int, int) Return the component that contains
theComponent getComponentAt(Point)specified x, y position. The
top-most child component is returned in the case where components
overlap. This is determined by finding the component closest to the
index 0 that claims to contain the given point via
Component.contains().Component setComponentZOrder(component comp,
Moves the specified component to the specifiedint index) z-order
index in the container. If the component is a child of some other
container, it is removed from that container before being added to
this container. The important difference between this method and
java.awt.Container.add(Component, int) is that this method doesnt
call removeNotify on the component while removing it from its
previous container unless necessary and when allowed by the
underlying native windowing system. This way, if the component has
the keyboard focus, it maintains the focus when moved to the new
position. Note: The z-order determines the order that components
are painted. The component with the highest z-order paints first
and the component with the lowest z-order paints last. 41. SHER
SINGH BARDHANs Where components overlap, the component with the
lower z-order paints over the component with the higher z-order.
Returns the z-order index of the componentComponent
getComponentZOrder(component comp) inside the container. The higher
a component is in the z-order hierarchy, the lower its index. The
component with the lowest z-order index is painted last, above all
other child components.Painting Components (see Performing Custom
Painting for details)MethodPurposevoid repaint() Request that all
or part of the component be repainted. The four intvoid
repaint(int, int, int, int) arguments specify the bounds (x, y,
width, height, in that order) of the rectangle to be painted.void
repaint(Rectangle) Request that the specified area within the
component be repainted.void revalidate() Request that the component
and its affected containers be laid out again.You should not
generally need to invoke this method unless you explicitlychange a
components size/alignment hints after its visible or change
acontainment hierarchy after it is visible. Always invoke repaint
afterrevalidate.void Paint the component. Override this method to
implement painting forpaintComponent(Graphics) custom
components.Dealing with the Containment Hierarchy(see Using
Top-Level Containers for more information)Method PurposeComponent
add(Component) Add the specified component to thisComponent
add(Component, int)container. The one-argument version of thisvoid
add(Component, Object)method adds the component to the end of the
container. When present, the int argument indicates the new
components position within the container. When present, 42. SHER
SINGH BARDHANsthe Object argument provides layoutconstraints to the
current layout manager.void remove(int)Remove one of or all of the
components fromvoid remove(Component)this container. When present,
the intvoid removeAll()argument indicates the position within
thecontainer of the component to remove.JRootPane getRootPane() Get
the root pane that contains thecomponent.Container
getTopLevelAncestor() Get the topmost container for the component a
Window, Applet, or null if thecomponent has not been added to
anycontainer.Container getParent() Get the components immediate
container.int getComponentCount() Get the number of components in
thiscontainer.Component getComponent(int) Get the one of or all of
the components in thisComponent[] getComponents() container. The
int argument indicates theposition of the component to
get.Component getComponentZOrder(int) Returns the z-order index of
the componentComponent[] getComponentZOrder()inside the container.
The higher a componentis in the z-order hierarchy, the lower its
index.The component with the lowest z-order indexis painted last,
above all other childcomponents. Laying Out Components(see Laying
Out Components Within a Container for more
information)MethodPurposevoid setPreferredSize(Dimension) Set the
components preferred, maximum, orvoid setMaximumSize(Dimension)
minimum size, measured in pixels. Thevoid setMinimumSize(Dimension)
preferred size indicates the best size for the component. The
component should be no larger than its maximum size and no smaller
43. SHER SINGH BARDHANs than its minimum size. Be aware that these
are hints only and might be ignored by certain layout
managers.Dimension getPreferredSize() Get the preferred, maximum,
or minimumDimension getMaximumSize() size of the component,
measured in pixels.Dimension getMinimumSize() Many JComponent
classes have setter and getter methods. For those non-JComponent
subclasses, which do not have the corresponding setter methods, you
can set a components preferred, maximum, or minimum size by
creating a subclass and overriding these methods.void
setAlignmentX(float)Set the alignment along the x- or y- axis.void
setAlignmentY(float)These values indicate how the component would
like to be aligned relative to other components. The value should
be a number between 0 and 1 where 0 represents alignment along the
origin, 1 is aligned the furthest away from the origin, and 0.5 is
centered, and so on. Be aware that these are hints only and might
be ignored by certain layout managers.float getAlignmentX()Get the
alignment of the component alongfloat getAlignmentY()the x- or y-
axis. For non-JComponent subclasses, which do not have the
corresponding setter methods, you can set a components alignment by
creating a subclass and overriding these methods.void
setLayout(LayoutManager)Set or get the components layout
manager.LayoutManager getLayout()The layout manager is responsible
for sizing and positioning the components within a container.void
Set the ComponentOrientation
propertyapplyComponentOrientation(ComponentOrientation)of this
container and all the componentsvoid
setComponentOrientation(ComponentOrientation) contained within it.
See Setting the Containers Orientation for more information. 44.
SHER SINGH BARDHANsGetting Size and Position Information
MethodPurposeint getWidth() Get the current width or height of the
component measured in pixels.int getHeight()Dimension getSize()Get
the components current size measured in pixels. When using the
one-Dimensionargument version of this method, the caller is
responsible for creating thegetSize(Dimension) Dimension instance
in which the result is returned.int getX() Get the current x or y
coordinate of the components origin relative to theint getY()
parents upper left corner measured in pixels.Rectangle
getBounds()Get the bounds of the component measured in pixels. The
bounds specify theRectanglecomponents width, height, and origin
relative to its parent. When using thegetBounds(Rectangle)
one-argument version of this method, the caller is responsible for
creating the Rectangle instance in which the result is
returned.Point getLocation()Gets the current location of the
component relative to the parents upper leftPoint
getLocation(Point) corner measured in pixels. When using the
one-argument version of getLocation method, the caller is
responsible for creating the Point instance in which the result is
returned.PointReturns the position relative to the upper left
corner of the screen.getLocationOnScreen()Insets getInsets() Get
the size of the components border. Specifying Absolute Size and
Position (see Doing Without a Layout Manager (Absolute Positioning)
for more information)MethodPurposevoid setLocation(int, Set the
location of the component, in pixels, relative to the parents upper
leftint)corner. The two int arguments specify x and y, in that
order. Use thesevoid setLocation(Point) methods to position a
component when you are not using a layout manager.void setSize(int,
int)Set the size of the component measured in pixels. The two int
argumentsvoid setSize(Dimension) specify width and height, in that
order. Use these methods to size acomponent when you are not using
a layout manager. 45. SHER SINGH BARDHANsvoid setBounds(int, int,
Set the size and location relative to the parents upper left
corner, in pixels, ofint, int)the component. The four int arguments
specify x, y, width, and height, in thatvoid order. Use these
methods to position and size a component when you are
notsetBounds(Rectangle) using a layout manager.Using Text
ComponentsThis section provides background information you might
need when using Swing textcomponents. If you intend to use an
unstyled text component a text field, password field,formatted text
field, or text area go to its how-to page and return here only if
necessary. If youintend to use a styled text component, see How to
Use Editor Panes and Text Panes, and read thissection as well. If
you do not know which component you need, read on.Swing text
components display text and optionally allow the user to edit the
text. Programs needtext components for tasks ranging from the
straightforward (enter a word and press Enter) to thecomplex
(display and edit styled text with embedded images in an Asian
language).Swing provides six text components, along with supporting
classes and interfaces that meet eventhe most complex text
requirements. In spite of their different uses and capabilities,
all Swingtext components inherit from the same superclass,
JTextComponent, which provides a highly-configurable and powerful
foundation for text manipulation.The following figure shows the
JTextComponent hierarchy.The following picture shows an application
called TextSamplerDemo that uses each Swing textcomponent. 46. SHER
SINGH BARDHANsTry this: 1. Click the Launch button to run
TextSamplerDemo using Java Web Start (downloadJDK 6).
Alternatively, to compile and run the example yourself, consult the
exampleindex. 2. Type some text in the text field and press Enter.
Do the same in the password field. Thelabel beneath the fields is
updated when you press Enter. 3. Try entering valid and invalid
dates into the formatted text field. Note that when youpress Enter
the label beneath the fields is updated only if the date is valid.
4. Select and edit text in the text area and the text pane. Use
keyboard bindings, Ctrl-X,Ctrl-C, and Ctrl-V, to cut, copy, and
paste text, respectively. 5. Try to edit the text in the editor
pane, which has been made uneditable with a call tosetEditable. 6.
Look in the text pane to find an example of an embedded component
and an embeddedicon.The TextSamplerDemo example uses the text
components in very basic ways. The followingtable tells you more
about what you can do with each kind of text component. 47. SHER
SINGH BARDHANs GroupDescription Swing Classes Also known simply as
text fields, text controls can display only one line of editable
text. Like buttons, JTextField and its Text they generate action
events. Use them to get a smallsubclasses JPasswordFieldControls
amount of textual information from the user and and
JFormattedTextField perform an action after the text entry is
complete. JTextArea can display multiple lines of editable text.
Although a text area can display text in anyPlain font, all of the
text is in the same font. Use a text JTextAreaText area to allow
the user to enter unformatted text ofAreas any length or to display
unformatted help information. A styled text component can display
editable text using more than one font. Some styled text components
allow embedded images and even embedded components. Styled text
components are powerful and multi-faceted components suitable for
high-end needs, and offer more avenues for StyledJEditorPane
customization than the other text components.Text and its subclass
Areas JTextPane Because they are so powerful and flexible, styled
text components typically require more initial programming to set
up and use. One exception is that editor panes can be easily loaded
with formatted text from a URL, which makes them useful for
displaying uneditable help information.This Tutorial provides
information about the foundation laid by the JTextComponent class
andtells you how to accomplish some common text-related tasks.
Because the JTextComponentclass and its subclasses have too many
features to be completely described in this Tutorial, pleasevisit
the Swing & AWT forum at java.net for help and information.Text
Component FeaturesThe JTextComponent class is the foundation for
Swing text components. This class provides thefollowing
customizable features for all of its descendants: A model, known as
a document, that manages the components content. A view, which
displays the component on screen. A controller, known as an editor
kit, that reads and writes text and implements editing capabilities
with actions. Support for infinite undo and redo. 48. SHER SINGH
BARDHANs A pluggable caret and support for caret change listeners
and navigation filters.See the example called TextComponentDemo to
explore these capabilities. Although theTextComponentDemo example
contains a customized instance of JTextPane, the
capabilitiesdiscussed in this section are inherited by all
JTextComponent subclasses.The upper text component is the
customized text pane. The lower text component is an instance
ofJTextArea, which serves as a log that reports all changes made to
the contents of the text pane. Thestatus line at the bottom of the
window reports either the location of the selection or the position
of thecaret, depending on whether text is selected.Try this:1.
Click the Launch button to run TextComponentDemo using Java Web
Start (download JDK 6). Alternatively, to compile and run the
example yourself, consult the example index.2. Use the mouse to
select text and place the cursor in the text pane. Information
about the selection and cursor is displayed at the bottom of the
window.3. Enter text by typing on the keyboard. You can move the
caret around using the arrow keys on the keyboard or the four emacs
key bindings: Ctrl-B (backward one character), Ctrl-F (forward one
character), Ctrl-N (down one line), and Ctrl-P (up one line). 49.
SHER SINGH BARDHANs 4. Open the Edit menu, and use its menu items
to edit text in the text pane. Make a selection inthe text area at
the bottom of the window. Because the text area is not editable,
only some ofthe Edit menus commands, like copy-to-clipboard, work.
It is important to note though, that themenu operates on both text
components. 5. Use the items in the Style menu to apply different
styles to the text in the text pane.Using the TextComponentDemo
example as a reference point, this section covers the following
topics: Associating Text Actions With Menus and Buttons Associating
Text Actions With Key Strokes Implementing Undo and Redo Concepts:
About Documents Implementing a Document Filter Listening for
Changes on a Document Listening for Caret and Selection Changes
Concepts: About Editor KitsAssociating Text Actions With Menus and
ButtonsAll Swing text components support standard editing commands
such as cut, copy, paste, and insertcharacters. Each editing
command is represented and implemented by an Action object. (To
learnmore about actions see How to Use Actions.) Actions allow you
to associate a command with a GUIcomponent, such as a menu item or
button, and therefore build a GUI around a text component.You can
invoke the getActions method on any text component to receive an
array containingall actions supported by this component. It is also
possible to load the array of actions into aHashMap so your program
can retrieve an action by name. Here is the code from
theTextComponentDemo example that takes the actions from the text
pane and loads them into aHashMap.private HashMap
createActionTable(JTextComponenttextComponent) {HashMap actions =
new HashMap();Action[] actionsArray =
textComponent.getActions();for (int i = 0; i <
actionsArray.length; i++) {Action a =
actionsArray[i];actions.put(a.getValue(Action.NAME), a);}return
actions;}Here is the method for retrieving an action by its name
from the hash map:private Action getActionByName(String name)
{return actions.get(name);}You can use both methods verbatim in
your programs. 50. SHER SINGH BARDHANsThe following code shows how
the cut menu item is created and associated with the action
ofremoving text from the text component.protected JMenu
createEditMenu() {JMenu menu = new
JMenu("Edit");...menu.add(getActionByName(DefaultEditorKit.cutAction));...This
code gets the action by name using the handy method shown
previously. It then adds the action tothe menu. That is all you
need to do. The menu and the action take care of everything else.
Note thatthe name of the action comes from DefaultEditorKit. This
kit provides actions for basic text editingand is the superclass
for all the editor kits provided by Swing. So its capabilities are
available to all textcomponents unless thay are overridden by a
customization.For efficiency, text components share actions. The
Action object returned
bygetActionByName(DefaultEditorKit.cutAction) is shared by the
uneditable JTextArea atthe bottom of the window. This sharing
characteristic has two important ramifications: Generally, you
should not modify Action objects you get from editor kits. If you
do, thechanges affect all text components in your program. Action
objects can operate on other text components in the program,
sometimes more thanyou intended. In this example, even though it is
not editable, the JTextArea shares actionswith the JTextPane.
(Select some text in the text area, then choose the
cut-to-clipboard menuitem. You will hear a beep because the text
area is not editable.) If you do not want to share,instantiate the
Action object yourself. DefaultEditorKit defines a number of
usefulAction subclasses.Here is the code that creates the Style
menu and puts the Bold menu item in it:protected JMenu
createStyleMenu() {JMenu menu = new JMenu("Style"); Action action =
new StyledEditorKit.BoldAction(); action.putValue(Action.NAME,
"Bold"); menu.add(action); ...The StyledEditorKit provides Action
subclasses to implement editing commands for styled text.You will
note that instead of getting the action from the editor kit, this
code creates an instance of theBoldAction class. Thus, this action
is not shared with any other text component, and changing itsname
will not affect any other text component.Associating Text Actions
With Key StrokesIn addition to associating an action with a GUI
component, you can also associate an action with a keystroke by
using a text components input map. Input maps are described in How
to Use Key Bindings.The text pane in the TextComponentDemo example
supports four key bindings not provided bydefault. 51. SHER SINGH
BARDHANs Ctrl-B to move the caret backward one character Ctrl-F to
move the caret forward one character Ctrl-N to move the caret down
one line Ctrl-P to move the caret up one lineThe following code
adds the Ctrl-B key binding to the text pane. The code for adding
the other threebindings listed above is similar.InputMap inputMap =
textPane.getInputMap();KeyStroke key =
KeyStroke.getKeyStroke(KeyEvent.VK_B,
Event.CTRL_MASK);inputMap.put(key,
DefaultEditorKit.backwardAction);First, the code obtains the text
components input map. Next, it finds a KeyStroke objectrepresenting
the Ctrl-B key sequence. Finally, the code binds the key stroke to
the Action thatmoves the cursor backward.Implementing Undo and
RedoImplementing undo and redo has two parts: Remembering undoable
edits. Implementing the undo and redo commands and providing a user
interface for them.Part 1: Remembering Undoable EditsTo support
undo and redo, a text component must remember each edit that
occurs, the order ofedits, and what is needed to undo each edit.
The example program uses an instance of theUndoManager class to
manage its list of undoable edits. The undo manager is created
where themember variables are declared:protected UndoManager undo =
new UndoManager();Now, let us look at how the program discovers
undoable edits and adds them to the undo manager.A document
notifies interested listeners whenever an undoable edit occurs on
the documentcontent. An important step in implementing undo and
redo is to register an undoable edit listeneron the document of the
text component. The following code adds an instance
ofMyUndoableEditListener to the text panes
document:doc.addUndoableEditListener(new
MyUndoableEditListener());The undoable edit listener used in our
example adds the edit to the undo managers list:protected class
MyUndoableEditListenerimplements UndoableEditListener {public void
undoableEditHappened(UndoableEditEvent e) {//Remember the edit and
update the
menusundo.addEdit(e.getEdit());undoAction.updateUndoState();redoAction.updateRedoState();}}
52. SHER SINGH BARDHANsNote that this method updates two objects:
undoAction and redoAction. These are the actionobjects attached to
the Undo and Redo menu items, respectively. The next step shows you
how tocreate the menu items and how to implement the two actions.
For general information about undoableedit listeners and undoable
edit events, see How to Write an Undoable Edit Listener.Note: By
default, each undoable edit undoes a single character entry. It is
possible with some effort togroup edits so that a series of key
strokes is combined into one undoable edit. Grouping edits in
thismanner would require you to define a class that intercepts
undoable edit events from the document,combining them if
appropriate and forwarding the results to your undoable edit
listener.Part 2: Implementing the Undo and Redo CommandsThe first
step in implementing undo and redo is to create the actions to put
in the Edit menu.JMenu menu = new JMenu("Edit");//Undo and redo are
actions of our own creationundoAction = new
UndoAction();menu.add(undoAction);redoAction = new
RedoAction();menu.add(redoAction);...The undo and redo actions are
implemented by custom AbstractAction subclasses: UndoActionand
RedoAction, respectively. These classes are inner classes of the
examples primary class.When the user invokes the undo command, the
actionPerformed method of the UndoActionclass is called:public void
actionPerformed(ActionEvent e) { try {undo.undo(); } catch
(CannotUndoException ex) {System.out.println("Unable to undo: " +
ex);ex.printStackTrace(); } updateUndoState();
redoAction.updateRedoState();}This method calls the undo managers
undo method and updates the menu items to reflect the newundo/redo
state.Similarly, when the user invokes the redo command, the
actionPerformed method of theRedoAction class is called:public void
actionPerformed(ActionEvent e) { 53. SHER SINGH BARDHANstry
{undo.redo();} catch (CannotRedoException ex)
{System.out.println("Unable to redo: " +
ex);ex.printStackTrace();}updateRedoState();undoAction.updateUndoState();}This
method is similar to undo, except that it calls the undo managers
redo method.Much of the code in the UndoAction and RedoAction
classes is dedicated to enabling anddisabling the actions as
appropriate of the current state, and changing the names of the
menuitems to reflect the edit to be undone or redone.Note: The
implementation of undo and redo in the TextComponentDemo example
was taken from theNotePad demo that comes with the JDK software.
Many programmers will also be able to copy thisimplementation of
undo/redo without modification.Concepts: About DocumentsLike other
Swing components, a text component separates its data (known as the
model) from its viewof the data. If you are not yet familiar with
the model-view split used by Swing components, refer toUsing
Models.A text components model is known as a document and is an
instance of a class that implementsthe Document interface. A
document provides the following services for a text
component:Contains the text. A document stores the textual content
in Element objects, which can represent any logical text structure,
such as paragraphs, or text runs that share styles. We do not
describe Element objects here. However, The Swing Connection has at
least one article on the subject.Provides support for editing the
text through the remove and insertString methods.Notifies document
listeners and undoable edit listeners of changes to the
text.Manages Position objects, which track a particular location
within the text even as the text is modified.Allows you to obtain
information about the text, such as its length, and segments of the
text as a string.The Swing text package contains a subinterface of
Document, StyledDocument, that adds support formarking up the text
with styles. One JTextComponent subclass, JTextPane, requires that
itsdocument be a StyledDocument rather than merely a Document. 54.
SHER SINGH BARDHANsThe javax.swing.text package provides the
following hierarchy of document classes, whichimplement specialized
documents for the various JTextComponent subclasses:A PlainDocument
is the default document for text fields, password fields, and text
areas.PlainDocument provides a basic container for text where all
the text is displayed in the same font.Even though an editor pane
is a styled text component, it uses an instance of PlainDocument
bydefault. The default document for a standard JTextPane is an
instance of DefaultStyledDocument a container for styled text in no
particular format. However, the document instance used by
anyparticular editor pane or text pane depends on the type of
content bound to it. If you use the setPagemethod to load text into
an editor pane or text pane, the document instance used by the pane
mightchange. Refer to How to Use Editor Panes and Text Panes for
details.Although you can set the document of a text component, it
is usually easier to allow it to setautomatically, and if
necessary, use a document filter to change how the text components
data isset. You can implement certain customizations either by
installing a document filter or byreplacing a text components
document with one of your own. For example, the text pane in
theTextComponentDemo example has a document filter that limits the
number of characters the textpane can contain.Implementing a
Document FilterTo implement a document filter, create a subclass of
DocumentFilter and then attach it to adocument using the
setDocumentFilter method defined in the AbstractDocument class.
Althoughit is possible to have documents that do not descend from
AbstractDocument, by default Swing textcomponents use
AbstractDocument subclasses for their documents.The
TextComponentDemo application has a document filter,
DocumentSizeFilter, that limitsthe number of characters that the
text pane can contain. Here is the code that creates the filter
andattaches it to the text panes document:...//Where member
variables are declared:JTextPane textPane;AbstractDocument
doc;static final int MAX_CHARACTERS = 300;...textPane = new
JTextPane(); 55. SHER SINGH BARDHANs...StyledDocument styledDoc =
textPane.getStyledDocument();if (styledDoc instanceof
AbstractDocument) {doc =
(AbstractDocument)styledDoc;doc.setDocumentFilter(new
DocumentSizeFilter(MAX_CHARACTERS));}To limit the characters
allowed in the document, DocumentSizeFilter overrides
theDocumentFilter classs insertString method, which is called each
time that text is inserted intothe document. It also overrides the
replace method, which is most likely to be called when the
userpastes in new text. In general, text insertion can result when
the user types or pastes in new text, orwhen the setText method is
called. Here is the DocumentSizeFilter classs implementation of
theinsertString method:public void insertString(FilterBypass fb,
int offs, String str, AttributeSet a)throws BadLocationException {
if ((fb.getDocument().getLength() + str.length()) 0 && i
< s.length() - 1) { ext = s.substring(i+1).toLowerCase(); }
return ext;}}Customizing the File ViewIn the Java look and feel,
the choosers list shows each files name and displays a small icon
thatrepresents whether the file is a true file or a directory. You
can customize this file view by creating acustom subclass of
FileView and using an instance of the class as an argument to the
setFileView 127. SHER SINGH BARDHANsmethod. The example uses an
instance of a custom class, implemented in ImageFileView.java,
asthe file choosers file view.fc.setFileView(new
ImageFileView());The ImageFileView class shows a different icon for
each type of image accepted by the image filterdescribed
previously.The ImageFileView class overrides the five abstract
methods defined in the FileView asfollows.String
getTypeDescription(File f) Returns a description of the file type.
Here is ImageFileViews implementation of this method: public String
getTypeDescription(File f) { String extension =
Utils.getExtension(f); String type = null; if (extension != null) {
if (extension.equals(Utils.jpeg) || extension.equals(Utils.jpg)) {
type = "JPEG Image"; } else if (extension.equals(Utils.gif)){ type
= "GIF Image"; } else if (extension.equals(Utils.tiff)
||extension.equals(Utils.tif)) { type = "TIFF Image"; } else if
(extension.equals(Utils.png)){ type = "PNG Image"; } } return
type;}Icon getIcon(File f) Returns an icon representing the file or
its type. Here is ImageFileViews implementation of this method:
public Icon getIcon(File f) { String extension =
Utils.getExtension(f); Icon icon = null; if (extension != null) {
if (extension.equals(Utils.jpeg) || extension.equals(Utils.jpg)) {
icon = jpgIcon; } else if (extension.equals(Utils.gif)){ icon =
gifIcon; } else if
(extension.equals(Utils.tiff)||extension.equals(Utils.tif)){ icon =
tiffIcon; } else if (extension.equals(Utils.png)){ icon = pngIcon;
128. SHER SINGH BARDHANs } } return icon;}String getName(File
f)Returns the name of the file. Most implementations of this method
should return null toindicate that the look and feel should figure
it out. Another common implementation returnsf.getName().String
getDescription(File f)Returns a description of the file. The intent
is to describe individual files more specifically. Acommon
implementation of this method returns null to indicate that the
look and feel shouldfigure it out.Boolean isTraversable(File
f)Returns whether a directory is traversable. Most implementations
of this method should returnnull to indicate that the look and feel
should figure it out. Some applications might want toprevent users
from descending into a certain type of directory because it
represents acompound document. The isTraversable method should
never return true for a non-directory.Providing an Accessory
ComponentThe customized file chooser in FileChooserDemo2 has an
accessory component. If the currentlyselected item is a PNG, JPEG,
TIFF, or GIF image, the accessory component displays a thumbnail
sketchof the image. Otherwise, the accessory component is empty.
Aside from a previewer, probably the mostcommon use for the
accessory component is a panel with more controls on it such as
checkboxes thattoggle between features.The example calls the
setAccessory method to establish an instance of the ImagePreview
class,implemented in ImagePreview.java, as the choosers accessory
component:fc.setAccessory(new ImagePreview(fc));Any object that
inherits from the JComponent class can be an accessory component.
The componentshould have a preferred size that looks good in the
file chooser.The file chooser fires a property change event when
the user selects an item in the list. Aprogram with an accessory
component must register to receive these events to update
theaccessory component whenever the selection changes. In the
example, the ImagePreview objectitself registers for these events.
This keeps all the code related to the accessory componenttogether
in one class.Here is the examples implementation of the
propertyChange method, which is the methodcalled when a property
change event is fired: 129. SHER SINGH BARDHANs//where member
variables are declaredFile file = null;...public void
propertyChange(PropertyChangeEvent e) {boolean update =
false;String prop = e.getPropertyName();//If the directory changed,
dont show an image.if
(JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(prop)) {file =
null;update = true;//If a file became selected, find out which
one.} else if
(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY.equals(prop)) {file =
(File) e.getNewValue();update = true;}//Update the preview
accordingly.if (update) {thumbnail = null;if (isShowing())
{loadImage();repaint();}}}If SELECTED_FILE_CHANGED_PROPERTY is the
property that changed, this method obtains a Fileobject from the
file chooser. The loadImage and repaint methods use the File object
to load theimage and repaint the accessory component.The File
Chooser APIThe API for using file choosers falls into these
categories:Creating and Showing the File ChooserSelecting Files and
DirectoriesNavigating the File Choosers ListCustomizing the File
ChooserCreating and Showing the File ChooserMethod or Constructor
PurposeJFileChooser()Creates a file chooser instance. The File and
String arguments,JFileChooser(File)when present, provide the
initial directory.JFileChooser(String)int Shows a modal dialog
containing the file chooser. These methodsshowOpenDialog(Component)
return APPROVE_OPTION if the user approved the operation and 130.
SHER SINGH BARDHANsintCANCEL_OPTION if the user cancelled it.
Another possible return valueshowSaveDialog(Component)is
ERROR_OPTION, which means an unanticipated error occurred.int
showDialog(Component,String)Selecting Files and DirectoriesMethod
Purposevoid setSelectedFile(File) Sets or obtains the currently
selected file or (if directory selectionFile getSelectedFile() has
been enabled) directory.void setSelectedFiles(File[])Sets or
obtains the currently selected files if the file chooser is
setFile[] getSelectedFiles()to allow multiple selection.void
setFileSelectionMode(int) Sets or obtains the file selection mode.
Acceptable values arevoid getFileSelectionMode()FILES_ONLY (the
default), DIRECTORIES_ONLY,
andbooleanFILES_AND_DIRECTORIES.isDirectorySelectionEnabled()Interprets
whether directories or files are selectable according toboolean
isFileSelectionEnabled() the current selection mode.void Sets or
interprets whether multiple files can be selected at
once.setMultiSelectionEnabled(boolean) By default, a user can
choose only one file.boolean isMultiSelectionEnabled()voidSets or
obtains whether the AcceptAll file filter is used as
ansetAcceptAllFileFilterUsed(boolean) allowable choice in the
choosable filter list; the default value isboolean
isAcceptAllFileFilterUsed() true. Given a parent component, creates
and returns a new dialog thatDialog createDialog(Component)
contains this file chooser, is dependent on the parents frame, and
is centered over the parent.Navigating the File Choosers ListMethod
Purposevoid ensureFileIsVisible(File) Scrolls the file choosers
list such that the indicated file is visible.void Sets or obtains
the directory whose files are displayed in the file
chooserssetCurrentDirectory(File)list. 131. SHER SINGH BARDHANsFile
getCurrentDirectory()void Changes the list to display the current
directorys parent.changeToParentDirectory()void Checks the file
system and updates the choosers list.rescanCurrentDirectory()void
Sets or obtains the property that determines whether automatic
dragsetDragEnabled(boolean)handling is enabled. See Drag and Drop
and Data Transfer for moreboolean getDragEnabled()
details.Customizing the File ChooserMethod
PurposevoidsetAccessory(javax.swing.JComponent) Sets or obtains the
file choosers accessory component.JComponent getAccessory()void
setFileFilter(FileFilter) Sets or obtains the file choosers primary
file filter.FileFilter getFileFilter()void setFileView(FileView)
Sets or obtains the choosers file view.FileView
getFileView()FileFilter[] getChoosableFileFilters()void
addChoosableFileFilter(FileFilter)boolean Sets, obtains, or
modifies the list of user-choosable file
filters.removeChoosableFileFilter(FileFilter)void
resetChoosableFileFilters()FileFilter getAcceptAllFileFilter()void
setFileHidingEnabled(boolean) Sets or obtains whether hidden files
are displayed.boolean isFileHidingEnabled()void Sets or obtains the
property that indicates whether
thesetControlButtonsAreShown(boolean) Approve and Cancel buttons
are shown in the file chooser.boolean
getControlButtonsAreShown()This property is true by default. 132.
SHER SINGH BARDHANsExamples That Use File ChoosersThis table shows
the examples that use file choosers and points to where those
examples are described.WhereExample NotesDescribedFileChooserDemo
This sectionDisplays an open dialog and a save dialog.Uses a file
chooser with custom filtering, a custom file
view,FileChooserDemo2This sectionand an accessory
component.JWSFileChooserDemo This section Uses the JNLP API to open
and save files.How to Use Formatted Text FieldsFormatted text
fields provide a way for developers to specify the valid set of
characters that can betyped in a text field. Specifically, the
JFormattedTextField class adds a formatter and an objectvalue to
the features inherited from the JTextField class. The formatter
translates the fields valueinto the text it displays, and the text
into the fields value.Using the formatters that Swing provides, you
can set up formatted text fields to type dates andnumbers in
localized formats. Another kind of formatter enables you to use a
character mask tospecify the set of characters that can be typed at
each position in the field. For example, you canspecify a mask for
typing phone numbers in a particular format, such as (XX)
X-XX-XX-XX-XX.If the possible values of a formatted text field have
an obvious order, use a spinner instead. Aspinner uses a formatted
text field by default, but adds two buttons that enable the user to
choosea value in a sequence.Another alternative or adjunct to using
a formatted text field is installing an input verifier on thefield.
A components input verifier is called when the component nearly
loses the keyboardfocus. The input verifier enables you to check
whether the value of the component is valid andoptionally change it
or stop the focus from being transferred.This GUI uses formatted
text fields to display numbers in four different formats. 133. SHER
SINGH BARDHANsTry this:1. Click the Launch button to run
FormattedTextFieldDemo using Java Web Start (download JDK 6).
Alternatively, to compile and run the example yourself, consult the
example index.2. Experiment with different loan amounts, annual
percentage rates (APRs), and loan lengths. Note that as long as the
text you type is valid, the Month Payment field is updated when you
press Enter or move the focus out of the field that you are
editing.3. Type invalid text such as "abcd" in the Loan Amount
field and then press Enter. The Month Payment field remains the
same. When you move the focus from the Loan Amount field, the text
reverts to the fields last valid value.4. Type marginally valid
text such as "2000abcd" in the Loan Amount field and press Enter.
The Monthly Payment field is updated, though the Loan Amount field
still displays 2000abcd. When you move the focus from the Loan
Amount field, the text it displays is updated to a neatly formatted
version of its value, for example, "2,000".You can find the entire
code for this program in FormattedTextFieldDemo.java. This code
createsthe first field.amountField = new
JFormattedTextField(amountFormat);amountField.setValue(new
Double(amount));amountField.setColumns(10);amountField.addPropertyChangeListener("value",
this);...amountFormat = NumberFormat.getNumberInstance();The
constructor used to create the amountField object takes a
java.text.Format argument.The Format object is used by the fields
formatter to translate the fields value to text and the textto the
fields value.The remaining code sets up the amountField object. The
setValue method sets the fields valueproperty to a floating-point
number represented as a Double object. The setColumns
method,inherited from the JTextField class, hints about the
preferred size of the field. The call to the 134. SHER SINGH
BARDHANsaddPropertyChangeListenermethod registers a listener for
the value property of the field, sothe program can update the
Monthly Payment field whenever the user changes the loan amount.The
rest of this section covers the following topics: Creating and
Initializing Formatted Text Fields Setting and Getting the Fields
Value Specifying Formats Using MaskFormatter Specifying Formatters
and Using Formatter FactoriesThis section does not explain the API
inherited from the JTextField class. That API isdescribed in How to
Use Text Fields.Creating and Initializing Formatted Text FieldsThe
following code creates and initializes the remaining three fields
in theFormattedTextFieldDemo example.rateField = new
JFormattedTextField(percentFormat);rateField.setValue(new
Double(rate));rateField.setColumns(10);rateField.addPropertyChangeListener("value",
this);numPeriodsField = new
JFormattedTextField();numPeriodsField.setValue(new
Integer(numPeriods));numPeriodsField.setColumns(10);numPeriodsField.addPropertyChangeListener("value",
this);paymentField = new
JFormattedTextField(paymentFormat);paymentField.setValue(new
Double(payment));paymentField.setColumns(10);paymentField.setEditable(false);paymentField.setForeground(Color.red);...percentFormat
=
NumberFormat.getNumberInstance();percentFormat.setMinimumFractionDigits(2);paymentFormat
= NumberFormat.getCurrencyInstance();The code for setting up the
rateField object is almost identical to the code listed previously
forother fields. The only difference is that the format is slightly
different, thanks to the
codepercentFormat.setMinimumFractionDigits(2).The code that creates
the numPeriodsField object does not explicitly set a format or
formatter.Instead, it sets the value to an Integer and enables the
field to use the default formatter forInteger objects. The code did
not do this in the previous two fields because the defaultformatter
is not being used for Double objects. The result was not what was
needed. How tospecify formats and formatters is covered later in
this section. 135. SHER SINGH BARDHANsThe payment field is
different from the other fields because it is uneditable, uses a
different colorfor its text, and does not have a property change
listener. Otherwise, it is identical to the otherfields. We could
have chosen to use a text field or label instead. Whatever the
component, wecould still use the paymentFormat method to parse the
payment amount into the text to bedisplayed.Setting and Getting the
Fields ValueKeep the following in mind when using a formatted text
field:A formatted text fields text and its value are two different
properties, and the value often lags behindthe text.The text
property is defined by the JTextField class. This property always
reflects what thefield displays. The value property, defined by the
JFormattedTextField class, might not reflectthe latest text
displayed in the field. While the user is typing, the text property
changes, but thevalue property does not change until the changes
are committed.To be more precise, the value of a formatted text
field can be set by using either the setValuemethod or the
commitEdit method. The setValue method sets the value to the
specifiedargument. The argument can technically be any Object, but
the formatter needs to be able toconvert it into a string.
Otherwise, the text field does not display any substantive
information.The commitEdit method sets the value to whatever object
the formatter determines isrepresented by the fields text. The
commitEdit method is automatically called when either ofthe
following happens: When the user presses Enter while the field has
the focus. By default, when the field loses the focus, for example,
when the user presses the Tab key tochange the focus to another
component. You can use the setFocusLostBehavior method tospecify a
different outcome when the field loses the focus.Note: Some
formatters might update the value constantly, rendering the loss of
focus meaningless, asthe value is always the same as what the text
specifies.When you set the value of a formatted text field, the
fields text is updated to reflect the value.Exactly how the value
is represented as text depends on the fields formatter. 136. SHER
SINGH BARDHANsNote that although the JFormattedTextField class
inherits the setText method from theJTextField class, you do not
usually call the setText method on a formatted text field. If
youdo, the fields display changes accordingly but the value is not
updated (unless the fieldsformatter updates it constantly).To
obtain a formatted text fields current value, use the getValue
method. If necessary, you canensure that the value reflects the
text by calling the commitEdit method before getValue.Because the
getValue method returns an Object, you need to cast it to the type
used for yourfields value. For example:Date enteredDate =
(Date)dateField.getValue();To detect changes in a formatted text
fields value, you can register a property change listener onthe
formatted text field to listen for changes to the "value" property.
The property change listeneris taken from the
FormattedTextFieldDemo example://The property change listener is
registered on each//field using code like
this://someField.addPropertyChangeListener("value", this);/**
Called when a fields "value" property changes. */public void
propertyChange(PropertyChangeEvent e) {Object source =
e.getSource();if (source == amountField) {amount =
((Number)amountField.getValue()).doubleValue();} else if (source ==
rateField) {rate = ((Number)rateField.getValue()).doubleValue();}
else if (source == numPeriodsField) {numPeriods =
((Number)numPeriodsField.getValue()).intValue();} double payment =
computePayment(amount, rate, numPeriods); paymentField.setValue(new
Double(payment));}Specifying FormatsThe Format class provides a way
to format locale-sensitive information such as dates and
numbers.Formatters that descend from the In