Kodo Millet PPT made by Ghanshyam bairwa college of Agriculture kumher bhara...
What is swing
1. SHER SINGH BARDHANs
What is Swing?
To create a Java program with a graphical user interface (GUI), you'll want to learn about Swing.
The Swing toolkit includes a rich set of components for building GUIs and adding interactivity
to Java applications. Swing includes all the components you would expect from a modern
toolkit: table controls, list controls, tree controls, buttons, and labels.
Swing is far from a simple component toolkit, however. It includes rich undo support, a highly
customizable text package, integrated internationalization and accessibility support. To truly
leverage the cross-platform capabilities of the Java platform, Swing supports numerous look and
feels, including the ability to create your own look and feel. The ability to create a custom look
and feel is made easier with Synth, a look and feel specifically designed to be customized. Swing
wouldn't be a component toolkit without the basic user interface primitives such as drag and
drop, event handling, customizable painting, and window management.
Swing is part of the Java Foundation Classes (JFC). The JFC also include other features
important to a GUI program, such as the ability to add rich graphics functionality and the ability
to create a program that can work in different languages and by users with different input
devices.
The following list shows some of the features that Swing and the Java Foundation Classes
provide.
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 Swing's 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, you'll want to use the Java 2D API. Because Swing is built on
the 2D package, it's trivial to make use of 2D within Swing components. Adding images,
drop shadows, compositing — it's 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.
Swing's 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
Swing's undo framework allows developers to provide support for undo and redo. Undo
support is built in to Swing's 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 BARDHANs
Flexible 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 showcases
many of these features. When you are ready to begin coding, the Creating GUI with JFC/Swing
trail provides the programming techniques to take advantage of these features
A Swing Demo
Here is an example of an application, PasswordStore, that illustrates some of Swing's rich feature
set. PasswordStore allows the user to manage login information for various hosts. It also
generates passwords, evaluates the effectiveness of a password, and allows you to store notes
about 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 Field
Table View
The Swing table component allows the user to rearrange the columns by dragging the
column header. Also, a column can be sorted by clicking the column header. If the
column you click on isn't highlighted as the primary sorted column, it will become the
primary sorted column in ascending order. Clicking on the primary sorted column toggles
the sort order. For example, if column 1 isn't selected, clicking on it will make it the
selected column and the data is sorted in ascending order. Clicking column 1 again will
sort the data in descending order. Clicking on column 2 will make column 2 the primary
column in ascending order.
5. SHER SINGH BARDHANs
Host Info (Table View)
Details/Notes Tabbed Pane
The tabbed pane below the host info allows the user to choose between the Details panel
and the Notes text pane, keeping the overall footprint of the window smaller and less
overwhelming.
Details Panel
The 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) support
cut/copy, paste, drag, drop, undo, and redo.
As the user enters or modifies the password, the 2D bar chart dynamically displays the
distribution of the password. If the list view is currently displayed, the corresponding
colored bar in the list also changes dynamically.
6. SHER SINGH BARDHANs
Notes Text Pane
This is the text component where the user can save notes about the selected host. If the
text pane contains a URI, Swing's text component provides the ability to click on the URI
and a browser window automatically opens to that location.
Wizzy 2D Graphics
PasswordStore uses customized graphics in several ways to enhance the UI: In the list
view, 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 Password
Visualizer, displays the distribution of a password. When you add an image, whether by
dragging and dropping it into the image well (in the Details panel) or by clicking the well
and 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 real
analysis of passwords.
7. SHER SINGH BARDHANs
2D Graphics Used
Multiple 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 don't 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 and
shows a sampling of Swing's capabilities. The Source Code is available for download, but it is
outside the scope of this chapter to discuss the implementation in detail.
NOTE: If PasswordStore were a production application, it would most likely encrypt the
password database; however, due to legal restrictions on distributing information of that nature,
it is not included here.
A Visual Guide to Swing Components (Java
Look and Feel)
This page shows Swing components in the Java look and feel. The following page shows the
same components in the Windows look and feel.
Basic Controls
Simple components that are used primarily to get input from the user; they may also show simple
state.
JButton
12. SHER SINGH BARDHANs
Uneditable Information Displays
These components exist solely to give the user information.
JLabel
JProgressBar
JSeparator
JToolTip
Top-Level Containers
At least one of these components must be present in any Swing application.
JApplet
15. SHER SINGH BARDHANs
JLayeredPane
Root pane
Pluggable Look and Feel
The Swing toolkit allows you to decide how to configure the particular look and feel of your application.
If you don't specify a look and feel, the Swing UI manager figures out which one to use. The options for
setting 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,
Swing's UI manager checks whether the user has specified a preference. If that preference
hasn't been specified or isn't available, the default look and feel is used. The default look and
feel is determined by the supplier of the JRE. For the JRE that Sun provides, the Java look and
feel (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 Microsoft
Windows XP machine, the Windows look and feel is used. On Mac OS platforms, the Aqua look
and feel is used. On UNIX platforms, such as Solaris or Linux, either the GTK+ look and feel or the
CDE/Motif look and feel is used, depending on the user's 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. The
Alloy look and feel has been provided courtesy of Incors.
Java look and feel
19. SHER SINGH BARDHANs
Default Alloy look and feel
Data Transfer
The Swing toolkit supports the ability to transfer data between components within the same Java
application, between different Java applications, and between Java and native applications. Data
can be transferred via a drag and drop gesture, or via the clipboard using cut, copy, and paste.
Drag and Drop
Drag-and-drop support can be easily enabled for many of Swing's components (sometimes with a
single line of code). For example, it's trivial to enable drag and drop and copy and paste support
for JTable, Swing's table component. All you need to provide is the data representing the
selection and how to get your data from the clipboard — that's it!
20. SHER SINGH BARDHANs
Cut, Copy, and Paste
Most of the text-based components, such as editor pane and text field, support cut/copy and paste
out of the box. Of course, menu items need to be created and "wired up" to the appropriate
actions. Other components, such as list and tree, can support cut, copy, and paste with some
minimal 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 support
cut/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 Localization
Internationalization is the process of designing an application so that the user can run it using his or her
cultural preferences without modifying or recompiling the code. These cultural preferences, collectively
known as locale, include (but aren't limited to): language, currency formatting, time and date
formatting, and numeric formatting.
An internationalized program is designed so that text elements, such as status messages and GUI
component labels, are stored outside the source code in resource bundles and retrieved
dynamically. Separating the locale-specific information from the code is what allows a program
to 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 that
locale, Swing grabs the localized strings from the resource bundle and the layout manager resizes
the component accordingly.
For example, an English-speaking person writes an application following the rules of
internationalization; later, that application is localized to Japanese and Spanish. When a user
with 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 the
components are scaled accordingly. If that user then quits the program, sets the language system
preference to Spanish, and re-launches the application, the application appears in Spanish, scaled
according to the new character set.
Swing's layout managers understand how locale affects a UI — it is not necessary to create a
new layout for each locale. For example, in a locale where text flows right to left, the layout
manager will arrange components in the same orientation, if specified. Bidi text (mixed
directional text, used by Hebrew and Arabic, for example) is supported as well.
21. SHER SINGH BARDHANs
Every program should be designed with internationalization in mind: GUI component labels,
status messages, currency, date, phone, and address formats should not be hardcoded into
programs. Once a program has been internationalized, a language expert can perform the actual
translation 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 Arabic
Accessibility
Assistive technologies exist to enable people with permanent or temporary disabilities to use the
computer. 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 the
United States, Australia, Canada, and the European Union, there are laws requiring that programs
function smoothly with assistive technologies. For more information, see Oracle's Accessibility Program.
A certain level of accessibility is built-in to all Swing components, but full accessibility can be
achieved 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, you
can see an example of tool tip text.
23. SHER SINGH BARDHANs
PasswordStore With a Tooltip
For more information, see How to Support Assistive Technologies.
Integrating with the Desktop
The 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 are
supported:
The ability to launch the host system's default browser with a specific Uniform Resource
Identifier (URI).
The ability to launch the host system's default email client.
The ability to launch applications to open, edit, or print files associated with those
applications.
24. SHER SINGH BARDHANs
You can see this in the PasswordStore demo in the Notes text pane. Click on the link that is
displayed in the text pane — it opens the specified URI in the default browser.
Click on the URI and it opens in the Default Browser
System Tray Icon Support
The desktop of some platforms, such as Microsoft Windows, includes a system tray, as shown in the
following screenshot:
On Microsoft Windows, it is called the "Taskbar Status Area." On Gnome, the "Notification
Area", and on KDE, the "System Tray." However it may be called, the system tray is shared by
all applications.
25. SHER SINGH BARDHANs
On 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 application's
status, or a need to take a particular action. Clicking the tray icon can bring up the application
window. A popup menu and a tooltip can also be attached to the tray icon.
System tray support was added in version 6 of Java SE. For more information, see the New
System Tray Functionality in Java SE 6 article.
About the JFC and Swing
JFC is short for Java Foundation Classes, which encompass a group of features for building graphical user
interfaces (GUIs) and adding rich graphics functionality and interactivity to Java applications. It is defined
as containing the features shown in the table below.
Feature Description
Includes everything from buttons to split panes to tables. Many components are
Swing GUI
capable of sorting, printing, and drag and drop, to name a few of the supported
Components
features.
The look and feel of Swing applications is pluggable, allowing a choice of look and
feel. For example, the same program can use either the Java or the Windows look
Pluggable Look-and-
and feel. Additionally, the Java platform supports the GTK+ look and feel, which
Feel Support
makes hundreds of existing look and feels available to Swing programs. Many
more look-and-feel packages are available from various sources.
Enables assistive technologies, such as screen readers and Braille displays, to get
Accessibility API
information from the user interface.
Enables developers to easily incorporate high-quality 2D graphics, text, and
Java 2D API images in applications and applets. Java 2D includes extensive APIs for generating
and sending high-quality output to printing devices.
Allows developers to build applications that can interact with users worldwide in
their own languages and cultural conventions. With the input method framework
Internationalization
developers can build applications that accept text in languages that use
thousands of different characters, such as Japanese, Chinese, or Korean.
This trail concentrates on the Swing components. We help you choose the appropriate
components for your GUI, tell you how to use them, and give you the background information
you need to use them effectively. We also discuss other JFC features as they apply to Swing
components.
26. SHER SINGH BARDHANs
Which Swing Packages Should I Use?
The Swing API is powerful, flexible — and immense. The Swing API has 18 public packages:
javax.accessibility javax.swing.plaf javax.swing.text
javax.swing javax.swing.plaf.basic javax.swing.text.html
javax.swing.border javax.swing.plaf.metal javax.swing.text.html.parser
javax.swing.colorchooser javax.swing.plaf.multi javax.swing.text.rtf
javax.swing.event javax.swing.plaf.synth javax.swing.tree
javax.swing.filechooser javax.swing.table javax.swing.undo
Fortunately, most programs use only a small subset of the API. This trail sorts out the API for
you, giving you examples of common code and pointing you to methods and classes you're likely
to 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 NetBeans
IDE
Examples Index
This lesson provides an introduction to Graphical User Interface (GUI) programming with Swing
and 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 the
Java programming language. It offers many advantages over coding with a text editor; we
recommend its use whenever possible. If you have not yet read the above lesson, please take a
moment to do so now. It provides valuable information about downloading and installing the
JDK and NetBeans IDE.
The goal of this lesson is to introduce the Swing API by designing a simple application that
converts temperature from Celsius to Fahrenheit. Its GUI will be basic, focusing on only a subset
of the available Swing components. We will use the NetBeans IDE GUI builder, which makes
user interface creation a simple matter of drag and drop. Its automatic code generation feature
simplifies the GUI development process, letting you focus on the application logic instead of the
underlying infrastructure.
27. SHER SINGH BARDHANs
Because this lesson is a step-by-step checklist of specific actions to take, we recommend that you
run the NetBeans IDE and perform each step as you read along. This will be the quickest and
easiest way to begin programming with Swing. If you are unable to do so, simply reading along
should still be useful, since each step is illustrated with screenshots.
If you prefer the traditional approach of programming each component manually (without the
assistance of an IDE), think of this lesson as an entry point into the lower-level discussions
already provided elsewhere in the tutorial. Hyperlinks in each discussion will take you to related
lessons, 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 the
example yourself, consult the
From an end-user's perspective, usage is simple: enter a temperature (in Celsius) into the text
box, click the "Convert" button, and watch the converted temperature (in Fahrenheit) appear on
screen. The minimize, maximize, and close buttons will behave as expected, and the application
will also have a title that appears along the top of the window.
From a programmer's perspective, we will write the application in two main stages. First, we will
populate 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 the
user presses the "Convert" button.
Setting up the CelsiusConverter Project
If you have worked with the NetBeans IDE in the past, much of this section will look familiar, since the
initial steps are similar for most projects. Still, the following steps describe settings that are specific to
this application, so take care to follow them closely.
Step 1: Create a New Project
To create a new project, launch the NetBeans IDE and choose New Project from the File menu:
28. SHER SINGH BARDHANs
Creating a New Project
Keyboard shortcuts for each command appear on the far right of each menu item. The look and feel of
the NetBeans IDE may vary across platforms, but the functionality will remain the same.
Step 2: Choose General -> Java Application
Next, 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 BARDHANs
You may notice mention of "J2SE" in the description pane; that is the old name for what is now
known as the "Java SE" platform. Press the button labeled "Next" to proceed.
Step 3: Set a Project Name
Now enter "CelsiusConverterProject" as the project name. You can leave the Project Location
and Project Folder fields set to their default values, or click the Browse button to choose an
alternate 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 a
new class as the main entry point for the application, but our main GUI window (created in the
next step) will serve that purpose, so checking this box is not necessary. Click the "Finish"
button when you are done.
30. SHER SINGH BARDHANs
This 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 be
empty except for the Projects pane in the upper left hand corner, which shows the newly created
project.
Step 4: Add a JFrame Form
This 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 is
the Swing class responsible for the main frame for your application.) You will learn how to
designate this class as the application's entry point later in this lesson.
31. SHER SINGH BARDHANs
Step 5: Name the GUI Class
Next, type CelsiusConverterGUI as the class name, and learn as the package name. You can
actually name this package anything you want, but here we are following the tutorial convention of
naming 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 Finish
button 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 BARDHANs
When the IDE finishes loading, the right pane will display a design-time, graphical view of the
CelsiusConverterGUI. It is on this screen that you will visually drag, drop, and manipulate the
various Swing components.
Using Top-Level Containers
As 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. We'll
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 container's 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 aren't actually top-level containers.
Here's a picture of a frame created by an application. The frame contains a green menu bar (with no
menus) and, in the frame's content pane, a large blank, yellow label.
33. SHER SINGH BARDHANs
You can find the entire source for this example in TopLevelDemo.java. Although the example
uses a JFrame in a standalone application, the same concepts apply to JApplets and JDialogs.
Here's the containment hierarchy for this example's GUI:
As the ellipses imply, we left some details out of this diagram. We reveal the missing details a bit
later. 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 Hierarchies
Each program that uses Swing components has at least one top-level container. This top-level container
is the root of a containment hierarchy — the hierarchy that contains all of the Swing components that
appear inside the top-level container.
As a rule, a standalone application with a Swing-based GUI has at least one containment
hierarchy with a JFrame as its root. For example, if an application has one main window and two
dialogs, then the application has three containment hierarchies, and thus three top-level
containers. One containment hierarchy has a JFrame as its root, and each of the other two has a
JDialog object as its root.
A Swing-based applet has at least one containment hierarchy, exactly one of which is rooted by a
JApplet 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 JApplet
object. The dialog has a containment hierarchy rooted by a JDialog object.
Adding Components to the Content Pane
Here's the code that the preceding example uses to get a frame's content pane and add the yellow label
to it:
frame.getContentPane().add(yellowLabel, BorderLayout.CENTER);
34. SHER SINGH BARDHANs
As the code shows, you find the content pane of a top-level container by calling the getContentPane
method. The default content pane is a simple intermediate container that inherits from JComponent,
and that uses a BorderLayout as its layout manager.
It's easy to customize the content pane — setting the layout manager or adding a border, for
example. However, there is one tiny gotcha. The getContentPane method returns a Container
object, not a JComponent object. This means that if you want to take advantage of the content
pane's JComponent features, you need to either typecast the return value or create your own
component to be the content pane. Our examples generally take the second approach, since it's a
little cleaner. Another approach we sometimes take is to simply add a customized component to
the content pane, covering the content pane completely.
Note that the default layout manager for JPanel is FlowLayout; you'll probably want to change
it.
To make a component the content pane, use the top-level container's 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 been
overridden to forward to the contentPane as necessary. This means you can write
frame.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 layout
set with setLayout().
Adding a Menu Bar
In theory, all top-level containers can hold a menu bar. In practice, however, menu bars usually appear
only 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 frame
with this code:
frame.setJMenuBar(greenMenuBar);
For more information about implementing menus and menu bars, see How to Use Menus.
35. SHER SINGH BARDHANs
The Root Pane
Each top-level container relies on a reclusive intermediate container called the root pane. The root pane
manages the content pane and the menu bar, along with a couple of other containers. You generally
don't need to know about root panes to use Swing components. However, if you ever need to intercept
mouse clicks or paint over multiple components, you should get acquainted with root panes.
Here's a list of the components that a root pane provides to a frame (and to every other top-level
container):
We've already told you about the content pane and the optional menu bar. The two other components
that a root pane adds are a layered pane and a glass pane. The layered pane contains the menu bar and
content pane, and enables Z-ordering of other components. The glass pane is often used to intercept
input events occuring over the top-level container, and can also be used to paint over multiple
components.
For more details, see How to Use Root Panes.
The JComponent Class
With the exception of top-level containers, all Swing components whose names begin with "J" descend
from the JComponent class. For example, JPanel, JScrollPane, JButton, and JTable all inherit
from JComponent. However, JFrame and JDialog don't because they implement top-level
containers.
The JComponent class extends the Container class, which itself extends Component. The
Component class includes everything from providing layout hints to supporting painting and
events. The Container class has support for adding components to the container and laying
them out. This section's API tables summarize the most often used methods of Component and
Container, as well as of JComponent.
JComponent Features
The 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 bindings
Tool tips
By specifying a string with the setToolTipText method, you can provide help to users of a
component. When the cursor pauses over the component, the specified string is displayed in a
small window that appears near the component. See How to Use Tool Tips for more
information.
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 doesn't 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 BARDHANs
Support for accessibility
The JComponent class provides API and basic functionality to help assistive technologies such
as screen readers get information from Swing components, For more information about
accessibility, see How to Support Assistive Technologies.
Support for drag and drop
The JComponent class provides API to set a component's transfer handler, which is the basis for
Swing's drag and drop support. See Introduction to DnD for details.
Double buffering
Double buffering smooths on-screen painting. For details, see Performing Custom Painting.
Key bindings
This feature makes components react when the user presses a key on the keyboard. For
example, in many look and feels when a button has the focus, typing the Space key is equivalent
to a mouse click on the button. The look and feel automatically sets up the bindings between
pressing and releasing the Space key and the resulting effects on the button. For more
information about key bindings, see How to Use Key Bindings.
The JComponent API
The JComponent class provides many new methods and inherits many methods from Component and
Container. 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 Appearance
Method Purpose
void Set or get the border of the component. See How to Use Borders for details.
setBorder(Border)
Border getBorder()
void Set the foreground or background color for the component. The foreground is
38. SHER SINGH BARDHANs
setForeground(Color) generally the color used to draw the text in a component. The background is
void (not surprisingly) the color of the background areas of the component, assuming
setBackground(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 its
setOpaque(boolean) background with its background color.
boolean isOpaque()
void setFont(Font) Set or get the component's 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 it
Cursor getCursor() contains (except for children that have their own cursor set). Example:
aPanel.setCursor( Cursor.getPredefinedCursor(
Cursor.WAIT_CURSOR));
Setting and Getting Component State
Method Purpose
void Sets the JPopupMenu for this JComponent. The UI is
setComponentPopupMenu(JPopupMenu) responsible for registering bindings and adding the
necessary listeners such that the JPopupMenu will be shown
at the appropriate time. When the JPopupMenu is shown
depends upon the look and feel: some may show it on a
mouse event, some may enable a key binding.
If popup is null, and getInheritsPopupMenu returns
true, then getComponentPopupMenu will be delegated to
the parent. This provides for a way to make all child
components inherit the popupmenu of the parent.
void setTransferHandler(TransferHandler) Set or remove the transferHandler property. The
TransferHandler 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 useful
String 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 enabled
boolean isEnabled() component can respond to user input and generate events.
void setVisible(boolean) Set or get whether the component is visible. Components
boolean isVisible() are initially visible, with the exception of top-level
components.
Handling Events
(see Writing Event Listeners for details)
Method Purpose
void addHierarchyListener(hierarchyListener l) Adds or removes the specified hierarchy listener
void 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 the
void 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 or
addMouseMotionListener(MouseMotionListener) from the component. Mouse motion listeners
void are notified when the user moves the mouse
removeMouseMotionListener(MouseMotionListener) within the listened-to component's bounds.
void addKeyListener(KeyListener) Add or remove a key listener to or from the
void 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 from
void removeComponentListener(ComponentListener) the component. Component listeners are
notified when the listened-to component is
hidden, shown, moved, or resized.
boolean contains(int, int) Determine whether the specified point is within
boolean contains(Point) the component. The argument should be
specified in terms of the component's coordinate
system. The two int arguments specify x and y
coordinates, respectively.
Component getComponentAt(int, int) Return the component that contains the
Component 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 specified
int 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 doesn't 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 component
Component 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)
Method Purpose
void repaint() Request that all or part of the component be repainted. The four int
void 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 explicitly
change a component's size/alignment hints after it's visible or change a
containment hierarchy after it is visible. Always invoke repaint after
revalidate.
void Paint the component. Override this method to implement painting for
paintComponent(Graphics) custom components.
Dealing with the Containment Hierarchy
(see Using Top-Level Containers for more information)
Method Purpose
Component add(Component) Add the specified component to this
Component add(Component, int) container. The one-argument version of this
void add(Component, Object) method adds the component to the end of
the container. When present, the int
argument indicates the new component's
position within the container. When present,
42. SHER SINGH BARDHANs
the Object argument provides layout
constraints to the current layout manager.
void remove(int) Remove one of or all of the components from
void remove(Component) this container. When present, the int
void removeAll() argument indicates the position within the
container of the component to remove.
JRootPane getRootPane() Get the root pane that contains the
component.
Container getTopLevelAncestor() Get the topmost container for the component
— a Window, Applet, or null if the
component has not been added to any
container.
Container getParent() Get the component's immediate container.
int getComponentCount() Get the number of components in this
container.
Component getComponent(int) Get the one of or all of the components in this
Component[] getComponents() container. The int argument indicates the
position of the component to get.
Component getComponentZOrder(int) Returns the z-order index of the component
Component[] getComponentZOrder() 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.
Laying Out Components
(see Laying Out Components Within a Container for more information)
Method Purpose
void setPreferredSize(Dimension) Set the component's preferred, maximum, or
void setMaximumSize(Dimension) minimum size, measured in pixels. The
void 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 minimum
Dimension 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
component's 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 along
float getAlignmentY() the x- or y- axis. For non-JComponent
subclasses, which do not have the
corresponding setter methods, you can set a
component's alignment by creating a subclass
and overriding these methods.
void setLayout(LayoutManager) Set or get the component's layout manager.
LayoutManager getLayout() The layout manager is responsible for sizing
and positioning the components within a
container.
void Set the ComponentOrientation property
applyComponentOrientation(ComponentOrientation) of this container and all the components
void setComponentOrientation(ComponentOrientation) contained within it. See Setting the
Container's Orientation for more information.
44. SHER SINGH BARDHANs
Getting Size and Position Information
Method Purpose
int getWidth() Get the current width or height of the component measured in pixels.
int getHeight()
Dimension getSize() Get the component's current size measured in pixels. When using the one-
Dimension argument version of this method, the caller is responsible for creating the
getSize(Dimension) Dimension instance in which the result is returned.
int getX() Get the current x or y coordinate of the component's origin relative to the
int getY() parent's upper left corner measured in pixels.
Rectangle getBounds() Get the bounds of the component measured in pixels. The bounds specify the
Rectangle component's width, height, and origin relative to its parent. When using the
getBounds(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 parent's upper left
Point 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.
Point Returns the position relative to the upper left corner of the screen.
getLocationOnScreen()
Insets getInsets() Get the size of the component's border.
Specifying Absolute Size and Position
(see Doing Without a Layout Manager (Absolute Positioning) for more information)
Method Purpose
void setLocation(int, Set the location of the component, in pixels, relative to the parent's upper left
int) corner. The two int arguments specify x and y, in that order. Use these
void 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 arguments
void setSize(Dimension) specify width and height, in that order. Use these methods to size a
component when you are not using a layout manager.
45. SHER SINGH BARDHANs
void setBounds(int, int, Set the size and location relative to the parent's upper left corner, in pixels, of
int, int) the component. The four int arguments specify x, y, width, and height, in that
void order. Use these methods to position and size a component when you are not
setBounds(Rectangle) using a layout manager.
Using Text Components
This section provides background information you might need when using Swing text
components. 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 you
intend to use a styled text component, see How to Use Editor Panes and Text Panes, and read this
section 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 need
text components for tasks ranging from the straightforward (enter a word and press Enter) to the
complex (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 even
the most complex text requirements. In spite of their different uses and capabilities, all Swing
text 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 text
component.
46. SHER SINGH BARDHANs
Try this:
1. Click the Launch button to run TextSamplerDemo using Java™ Web Start (download
JDK 6). Alternatively, to compile and run the example yourself, consult the example
index.
2. Type some text in the text field and press Enter. Do the same in the password field. The
label beneath the fields is updated when you press Enter.
3. Try entering valid and invalid dates into the formatted text field. Note that when you
press 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 to
setEditable.
6. Look in the text pane to find an example of an embedded component and an embedded
icon.
The TextSamplerDemo example uses the text components in very basic ways. The following
table tells you more about what you can do with each kind of text component.
47. SHER SINGH BARDHANs
Group Description 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 small subclasses JPasswordField
Controls
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 any
Plain
font, all of the text is in the same font. Use a text JTextArea
Text
area to allow the user to enter unformatted text of
Areas
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
Styled JEditorPane
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 and
tells you how to accomplish some common text-related tasks. Because the JTextComponent
class and its subclasses have too many features to be completely described in this Tutorial, please
visit the Swing & AWT forum at java.net for help and information.
Text Component Features
The JTextComponent class is the foundation for Swing text components. This class provides the
following customizable features for all of its descendants:
A model, known as a document, that manages the component's 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 the
TextComponentDemo example contains a customized instance of JTextPane, the capabilities
discussed 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 of
JTextArea, which serves as a log that reports all changes made to the contents of the text pane. The
status line at the bottom of the window reports either the location of the selection or the position of the
caret, 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 in
the text area at the bottom of the window. Because the text area is not editable, only some of
the Edit menu's commands, like copy-to-clipboard, work. It is important to note though, that the
menu 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 Kits
Associating Text Actions With Menus and Buttons
All Swing text components support standard editing commands such as cut, copy, paste, and insert
characters. Each editing command is represented and implemented by an Action object. (To learn
more about actions see How to Use Actions.) Actions allow you to associate a command with a GUI
component, 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 containing
all actions supported by this component. It is also possible to load the array of actions into a
HashMap so your program can retrieve an action by name. Here is the code from the
TextComponentDemo example that takes the actions from the text pane and loads them into a
HashMap.
private HashMap<Object, Action> createActionTable(JTextComponent
textComponent) {
HashMap<Object, Action> actions = new HashMap<Object, Action>();
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 BARDHANs
The following code shows how the cut menu item is created and associated with the action of
removing 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 to
the menu. That is all you need to do. The menu and the action take care of everything else. Note that
the name of the action comes from DefaultEditorKit. This kit provides actions for basic text editing
and is the superclass for all the editor kits provided by Swing. So its capabilities are available to all text
components unless thay are overridden by a customization.
For efficiency, text components share actions. The Action object returned by
getActionByName(DefaultEditorKit.cutAction) is shared by the uneditable JTextArea at
the 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, the
changes affect all text components in your program.
Action objects can operate on other text components in the program, sometimes more than
you intended. In this example, even though it is not editable, the JTextArea shares actions
with the JTextPane. (Select some text in the text area, then choose the cut-to-clipboard menu
item. 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 useful
Action 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 the
BoldAction class. Thus, this action is not shared with any other text component, and changing its
name will not affect any other text component.
Associating Text Actions With Key Strokes
In addition to associating an action with a GUI component, you can also associate an action with a key
stroke by using a text component's 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 by
default.
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 line
The following code adds the Ctrl-B key binding to the text pane. The code for adding the other three
bindings 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 component's input map. Next, it finds a KeyStroke object
representing the Ctrl-B key sequence. Finally, the code binds the key stroke to the Action that
moves the cursor backward.
Implementing Undo and Redo
Implementing 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 Edits
To support undo and redo, a text component must remember each edit that occurs, the order of
edits, and what is needed to undo each edit. The example program uses an instance of the
UndoManager class to manage its list of undoable edits. The undo manager is created where the
member 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 document
content. An important step in implementing undo and redo is to register an undoable edit listener
on the document of the text component. The following code adds an instance of
MyUndoableEditListener to the text pane's document:
doc.addUndoableEditListener(new MyUndoableEditListener());
The undoable edit listener used in our example adds the edit to the undo manager's list:
protected class MyUndoableEditListener
implements UndoableEditListener {
public void undoableEditHappened(UndoableEditEvent e) {
//Remember the edit and update the menus
undo.addEdit(e.getEdit());
undoAction.updateUndoState();
redoAction.updateRedoState();
}
}
52. SHER SINGH BARDHANs
Note that this method updates two objects: undoAction and redoAction. These are the action
objects attached to the Undo and Redo menu items, respectively. The next step shows you how to
create the menu items and how to implement the two actions. For general information about undoable
edit 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 to
group edits so that a series of key strokes is combined into one undoable edit. Grouping edits in this
manner 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 Commands
The 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 creation
undoAction = new UndoAction();
menu.add(undoAction);
redoAction = new RedoAction();
menu.add(redoAction);
...
The undo and redo actions are implemented by custom AbstractAction subclasses: UndoAction
and RedoAction, respectively. These classes are inner classes of the example's primary class.
When the user invokes the undo command, the actionPerformed method of the UndoAction
class 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 manager's undo method and updates the menu items to reflect the new
undo/redo state.
Similarly, when the user invokes the redo command, the actionPerformed method of the
RedoAction class is called:
public void actionPerformed(ActionEvent e) {
53. SHER SINGH BARDHANs
try {
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 manager's redo method.
Much of the code in the UndoAction and RedoAction classes is dedicated to enabling and
disabling the actions as appropriate of the current state, and changing the names of the menu
items to reflect the edit to be undone or redone.
Note: The implementation of undo and redo in the TextComponentDemo example was taken from the
NotePad demo that comes with the JDK software. Many programmers will also be able to copy this
implementation of undo/redo without modification.
Concepts: About Documents
Like other Swing components, a text component separates its data (known as the model) from its view
of the data. If you are not yet familiar with the model-view split used by Swing components, refer to
Using Models.
A text component's model is known as a document and is an instance of a class that implements
the 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 for
marking up the text with styles. One JTextComponent subclass, JTextPane, requires that its
document be a StyledDocument rather than merely a Document.
54. SHER SINGH BARDHANs
The javax.swing.text package provides the following hierarchy of document classes, which
implement 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 by
default. 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 any
particular editor pane or text pane depends on the type of content bound to it. If you use the setPage
method to load text into an editor pane or text pane, the document instance used by the pane might
change. 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 set
automatically, and if necessary, use a document filter to change how the text component's data is
set. You can implement certain customizations either by installing a document filter or by
replacing a text component's document with one of your own. For example, the text pane in the
TextComponentDemo example has a document filter that limits the number of characters the text
pane can contain.
Implementing a Document Filter
To implement a document filter, create a subclass of DocumentFilter and then attach it to a
document using the setDocumentFilter method defined in the AbstractDocument class. Although
it is possible to have documents that do not descend from AbstractDocument, by default Swing text
components use AbstractDocument subclasses for their documents.
The TextComponentDemo application has a document filter, DocumentSizeFilter, that limits
the number of characters that the text pane can contain. Here is the code that creates the filter and
attaches it to the text pane's 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 the
DocumentFilter class's insertString method, which is called each time that text is inserted into
the document. It also overrides the replace method, which is most likely to be called when the user
pastes in new text. In general, text insertion can result when the user types or pastes in new text, or
when the setText method is called. Here is the DocumentSizeFilter class's implementation of the
insertString method:
public void insertString(FilterBypass fb, int offs,
String str, AttributeSet a)
throws BadLocationException {
if ((fb.getDocument().getLength() + str.length()) <= maxCharacters)
super.insertString(fb, offs, str, a);
else
Toolkit.getDefaultToolkit().beep();
}
The code for replace is similar. The FilterBypass parameter to the methods defined by the
DocumentFilter class is simply an object that enables the document to be updated in a thread-
safe way.
Because the preceding document filter is concerned with additions to the document's data, it only
overrides the insertString and replace methods. Most document filters would override
DocumentFilter's remove method as well.
Listening for Changes on a Document
You can register two different types of listeners on a document: document listeners and undoable edit
listeners. This subsection describes document listeners. For information about undoable edit listeners,
refer to Implementing Undo and Redo.
A document notifies registered document listeners of changes to the document. Use a document
listener to create a reaction when text is inserted or removed from a document, or when the text
style changes.
The TextComponentDemo program uses a document listener to update the change log whenever a
change is made to the text pane. The following line of code registers an instance of the
MyDocumentListener class as a listener on the text pane's document:
doc.addDocumentListener(new MyDocumentListener());
Here is the implementation of the MyDocumentListener class:
protected class MyDocumentListener implements DocumentListener {
56. SHER SINGH BARDHANs
public void insertUpdate(DocumentEvent e) {
displayEditInfo(e);
}
public void removeUpdate(DocumentEvent e) {
displayEditInfo(e);
}
public void changedUpdate(DocumentEvent e) {
displayEditInfo(e);
}
private void displayEditInfo(DocumentEvent e) {
Document document = (Document)e.getDocument();
int changeLength = e.getLength();
changeLog.append(e.getType().toString() + ": "
+ changeLength + " character"
+ ((changeLength == 1) ? ". " : "s. ")
+ " Text length = " + document.getLength()
+ "." + newline);
}
}
The listener implements three methods for handling three different types of document events:
insertion, removal, and style changes. StyledDocument instances can fire all three types of events.
PlainDocument instances fire events only for insertion and removal. For general information about
document listeners and document events, see How to Write a Document Listener.
Remember that the document filter for this text pane limits the number of characters allowed in
the document. If you try to add more text than the document filter allows, the document filter
blocks the change and the listener's insertUpdate method is not called. Document listeners are
notified of changes only if the change has already occurred.
You may want to change the document's text within a document listener. However, you should
never modify the contents of a text component from within a document listener. If you do,
the program will likely deadlock. Instead, you can use a formatted text field or provide a
document filter.
Listening for Caret and Selection Changes
The TextComponentDemo program uses a caret listener to display the current position of the caret or,
if text is selected, the extent of the selection.
The caret listener class in this example is a JLabel subclass. Here is the code that creates the
caret listener label and makes it a caret listener of the text pane:
//Create the status area
CaretListenerLabel caretListenerLabel = new CaretListenerLabel(
"Caret Status");
...
textPane.addCaretListener(caretListenerLabel);
A caret listener must implement one method, caretUpdate, which is called each time the caret moves
or the selection changes. Here is the CaretListenerLabel implementation of caretUpdate:
public void caretUpdate(CaretEvent e) {
57. SHER SINGH BARDHANs
//Get the location in the text
int dot = e.getDot();
int mark = e.getMark();
if (dot == mark) { // no selection
try {
Rectangle caretCoords = textPane.modelToView(dot);
//Convert it to view coordinates
setText("caret: text position: " + dot +
", view location = [" +
caretCoords.x + ", " + caretCoords.y + "]" +
newline);
} catch (BadLocationException ble) {
setText("caret: text position: " + dot + newline);
}
} else if (dot < mark) {
setText("selection from: " + dot + " to " + mark + newline);
} else {
setText("selection from: " + mark + " to " + dot + newline);
}
}
As you can see, this listener updates its text label to reflect the current state of the caret or selection.
The listener gets the information to display from the caret event object. For general information about
caret listeners and caret events, see How to Write a Caret Listener.
As with document listeners, a caret listener is passive. It reacts to changes in the caret or in the
selection, but does not change the caret or the selection itself. If you want to change the caret or
selection, use a navigation filter or a custom caret.
Implementing a navigation filter is similar to implementing a document filter. First, write a
subclass of NavigationFilter. Then attach an instance of the subclass to a text component with
the setNavigationFilter method.
You might create a custom caret to customize the appearance of a caret. To create a custom
caret, write a class that implements the Caret interface — perhaps by extending the
DefaultCaret class. Then provide an instance of your class as an argument to the setCaret
method on a text component.
Concepts: About Editor Kits
Text components use an EditorKit to tie the various pieces of the text component together. The
editor kit provides the view factory, document, caret, and actions. An editor kit also reads and
writes documents of a particular format. Although all text components use editor kits, some
components hide theirs. You cannot set or get the editor kit used by a text field or text area.
Editor panes and text panes provide the getEditorKit method to get the current editor kit and
the setEditorKit method to change it.
For all components, the JTextComponent class provides the API for you to indirectly invoke or
customize some editor kit capabilities. For example, JTextComponent provides the read and
58. SHER SINGH BARDHANs
write methods, which invoke the editor kit's read and write methods. JTextComponent also
provides a method, getActions, which returns all of the actions supported by a component.
The Swing text package provides the following editor kits:
DefaultEditorKit
Reads and writes plain text, and provides a basic set of editing commands. Details about how
the text system treats newlines can be found in the DefaultEditorKit API documentation.
Briefly, the 'n' character is used internally, but the document or platform line separators are
used when writing files. All the other editor kits are descendants of the DefaultEditorKit
class.
StyledEditorKit
Reads and writes styled text, and provides a minimal set of actions for styled text. This class is a
subclass of DefaultEditorKit and is the editor kit used by JTextPane by default.
HTMLEditorKit
Reads, writes, and edits HTML. This is a subclass of StyledEditorKit.
Each of the editor kits listed above has been registered with the JEditorPane class and associated
with the text format that the kit reads, writes, and edits. When a file is loaded into an editor pane, the
pane checks the format of the file against its registered kits. If a registered kit is found that supports that
file format, the pane uses the kit to read the file, display, and edit it. Thus, the editor pane effectively
transforms itself into an editor for that text format. You can extend JEditorPane to support your own
text format by creating an editor kit for it, and then using JEditorPane's
registerEditorKitForContentType to associate your kit with your text format
The Text Component API
This section lists commonly used parts of the API that are shared by text components. Much of
this API is defined by the JTextComponent class. Text Component Features discusses how to
use some of this API.
The JComponent Class describes the API that text components inherit from JComponent. For
information about the API related to specific text components, see the how-to page for that
component: text field, password field, formatted text field, text area, or editor pane and text pane.
For complete details about the text API, see the API documentation for JTextComponent and for
the various classes and interfaces in the text package.
The API listed in this section includes the following categories:
59. SHER SINGH BARDHANs
Setting Attributes
Manipulating the Selection
Converting Positions Between the Model and the View
Text Editing Commands
Classes and Interfaces That Represent Documents
Working With Documents
Manipulating Carets and Selection Highlighters
Reading and Writing Text
Setting Attributes
These methods are defined in the JTextComponent class.
Method Description
void setEditable(boolean) Sets or indicates whether the user can edit the text in the text
boolean isEditable() component.
Sets or gets the dragEnabled property, which must be true to
void setDragEnabled(boolean)
enable drag handling on this component. The default value is
boolean getDragEnabled()
false. See Drag and Drop and Data Transfer for more details.
void
Sets or gets the color used to display text when the text
setDisabledTextColor(Color)
component is disabled.
Color getDisabledTextColor()
void setMargin(Insets) Sets or gets the margin between the text and the text component's
Insets getMargin() border.
Manipulating the Selection
These methods are defined in the JTextComponent class.
Method Description
String getSelectedText() Gets the currently selected text.
void selectAll()
Selects all text or selects text within a start and end range.
void select(int, int)
void setSelectionStart(int)
void setSelectionEnd(int)
Sets or gets the extent of the current selection by index.
int getSelectionStart()
int getSelectionEnd()
void setSelectedTextColor(Color)
Sets or gets the color of selected text.
Color getSelectedTextColor()
void setSelectionColor(Color)
Sets or gets the background color of selected text.
Color getSelectionColor()
Converting Positions Between the Model and the View
These methods are defined in the JTextComponent class.
Method Description
Converts the specified point in the view coordinate system to a
int viewToModel(Point)
position within the text.
60. SHER SINGH BARDHANs
Rectangle Converts the specified position within the text to a rectangle in the
modelToView(int) view coordinate system.
Text Editing Commands
Class or Method Description
void cut()
void copy()
Cuts, copies, and pastes text using the system clipboard, or replaces
void paste()
the selected text with the string specified by an argument,
void
respectively.
replaceSelection(String)
(in JTextComponent)
Provides a text component's view factory, document, caret, and
EditorKit actions, as well as reading and writing documents of a particular
format.
A concrete subclass of EditorKit that provides the basic text editing
DefaultEditorKit
capabilities.
A subclass of Default EditorKit that provides additional editing
StyledEditorKit
capabilities for styled text.
String xxxxAction The names of all the actions supported by the default editor kit. See
(in DefaultEditorKit) Associating Text Actions with Menus and Buttons.
BeepAction
CopyAction
CutAction
DefaultKeyTypedAction
InsertBreakAction Inner classes that implement various text editing commands.
InsertContentAction
InsertTabAction
PasteAction
(in DefaultEditorKit)
AlignmentAction
BoldAction
FontFamilyAction
FontSizeAction
Inner classes that implement various editing commands for styled
ForegroundAction
text.
ItalicAction
StyledTextAction
UnderlineAction
(in StyledEditorKit)
Action[] getActions() Gets the actions supported by this component. This method gets the
(in JTextComponent) array of actions from the editor kit if one is used by the component.
InputMap getInputMap() Gets the input map that binds key strokes to actions. See Associating
(in JComponent) Text Actions with Key Strokes.
void put(KeyStroke, Binds the specified key to the specified action. You generally specify