Start of Tutorial > Start of Trail > Start of Lesson | Search |
This section picks apart a Swing program, calledConverter
, that has a GUI. You can see how this program is implemented by looking at its source code, which is mainly inConverter.java
andConversionPanel.java
. However, this section doesn't talk about individual lines of code. Instead, it concentrates on how theConverter
program uses the GUI features provided by the Java platform. If you get lost while looking at theConverter
source code, you might want to refresh your memory by going to A Quick Tour of a Swing Application's Code.
Converter
is an application that converts distance measurements between metric and U.S. units. To run it, compile the seven source files listed in the Examples Index. Once you've compiled the program, run it by invoking the interpreter on theConverter
class. If you need help compiling or runningConverter
, see Compiling and Running a Swing Program.Here is an annotated snapshot of
Converter
's GUI:
This section discusses the following features of
Converter
:
As the preceding figure shows,Converter
has the following visible components:
- One
JFrame
- Two custom
JPanel
s- Two custom
JTextField
s- Two
JSlider
s- Two
JComboBox
esThe
JFrame
is the top-level container; it provides the only window in the application. All the other components in the application are contained by theJFrame
.Except for the top-level container, all the visible components in
Converter
inherit fromJComponent
. TheJComponent
class provides many features, such as support for borders and accessibility. The two customJPanel
s shown in the snapshot use the border support to provide titles (for example, "Metric System") and to paint boxes around themselves.
The following figure shows the containment hierarchy for theJFrame
:This diagram shows three components not labeled in the preceding snapshot because they don't paint anything noticeable on-screen:
- One
JPanel
that serves as the content pane- Two custom
JPanel
s that each hold a text field and sliderThese three components exist to affect layout. They do this either by simplifying layout or by adding "empty" borders that add space to the layout. Grouping components -- whether in visible or invisible containers -- also provides hints to assistive technologies. For example, grouping a text field and slider in their own container gives assistive technologies the information that the text field and slider might be closely related.
Under the content pane are two
ConversionPanel
s. One of theConversionPanel
s holds the components related to metric distances; the other one does the same for U.S. distances.Each
ConversionPanel
contains three visible components: a text field, a slider, and a combo box. The text field and slider are grouped together in aJPanel
, mainly to make layout simpler.
The following figure shows a colorized version ofConverter
. In this version, each container has a background color, so that you can easily see the parts of the containers that aren't covered by other components. Note that all the containers are opaque; otherwise, the background color would not automatically be painted on the container.Converter
creates five layout manager objects -- one instance ofGridLayout
and four ofBoxLayout
.The first
JPanel
(the custom content pane) usesGridLayout
to make theConversionPanel
s exactly equal in size. The code sets up theGridLayout
so that it puts theConversionPanel
s in a single column (two rows), with five pixels between components. TheJPanel
is initialized to have an empty border that adds five pixels between the panel and the sides of the frame.Each
ConversionPanel
has a compound border. On the outside is a titled border, and on the inside is an empty border. The titled border paints a look-and-feel-specific box around theConversionPanel
and places the panel's title in the box. The empty border puts some more space between theConversionPanel
and its contents.Each
ConversionPanel
uses aBoxLayout
manager to place its contents, aJPanel
and aJComboBox
, in a row. By setting the Y alignment of both the panel and combo box, the program aligns the top of the panel with the top of the combo box.The
JPanel
that groups the text field and slider is implemented with an unnamed subclass ofJPanel
. This subclass overrides thegetMinimumSize
,getPreferredSize
, andgetMaximumSize
methods so that they all return the same value: 150 pixels wide and the preferred height. This is how we ensure that both text-slider groups have the same width, even though they're controlled by different layout managers. We need to create a subclass ofJPanel
, instead of just calling thesetXxxxSize
methods, because the preferred height of components is determined at run time, by the layout manager.The
JPanel
that groups the text field and slider uses a top-to-bottomBoxLayout
manager so that the text field is placed on top of the slider. This panel also has an empty border that adds a bit of space to its right, between it and the combo box.
This program uses three custom models. The first is a data model for the text fields. Text data models are known as document models. The document model parses the value that the user enters into the text field. It also formats the number so that it looks nice. We borrowed this document model, without changing it, from the example presented in Creating a Validated Text Field.The other two custom models are slider data models. They ensure that the data displayed by the application is kept in only one place -- in the model for the top slider. The top slider's model is an instance of a custom class called
ConverterRangeModel
. The bottom slider uses a second custom class,FollowerRangeModel
, which forwards all requests to get and set data to the top slider's model.All slider data models must implement the
BoundedRangeModel
interface. We learned this by looking at the API section of How to Use Sliders. TheBoundedRangeModel
API documentation tells us that the interface has an implementing class namedDefaultBoundedRangeModel
. The API documentation forDefaultBoundedRangeModel
shows that it's a general-purpose implementation ofBoundedRangeModel
.We didn't use
DefaultBoundedRangeModel
directly because it stores data as integers, and we need to store floating-point data. Thus, we implementedConverterRangeModel
as a subclass ofObject
, checking it against theDefaultBoundedRangeModel
source code (distributed with the JFC 1.1 and JDK 1.2 releases), to make sure we implemented the model correctly. We then implementedFollowerRangeModel
as a subclass ofConverterRangeModel
.
TheConverter
program sets itself up to use the Java Look & Feel. By changing the value of itsLOOKANDFEEL
variable, you can make it use a different look and feel. Three of its incarnations are pictured in What Are the JFC and Swing?.
TheConverter
program creates several event handlers:Most of the
- Action listeners
- Each combo box has an action listener. Whenever the user selects a new unit of measure, the action listener notifies the relevant slider's model and resets the maximum values of both sliders.
Each text field has an action listener that's notified when the user presses Return to indicate that typing has ended. This action listener updates the corresponding slider's model to reflect the text field's value.
- Change listeners
- Each slider model has a custom change listener. Whenever a slider's value changes, the custom change listener updates the appropriate text field. We didn't have to register the sliders as listeners on their own models, since Swing automatically does so. In other words, whenever a program sets a value in a slider's model, that slider is automatically updated to reflect the model's new state.
The model for the bottom slider adds a change listener to the top slider's model. This change listener fires a change event to the bottom slider model's change listeners, which are the bottom slider and the custom change listener described in the previous paragraph. The effect is that when the top slider's value changes, the value displayed in the bottom slider and text field is updated. It isn't necessary to notify the top slider of changes in the bottom slider, since the bottom slider's model forwards all data-setting requests to the top slider's model.
- Window listener
- A window listener on the frame causes the application to exit when the window is closed.
Converter
program's listeners are implemented in anonymous inner classes. Although inner classes might seem hard to read, at first, they actually make code easier to understand, once you're used to them. By keeping an event handler implementation close to where the event handler is registered, inner classes help you, and those who follow you, to easily find the entire implementation of the event handler. See Using Adapters and Inner Classes to Handle Events for more information.
Start of Tutorial > Start of Trail > Start of Lesson | Search |