System, but they may not be reproduced for publication



Yüklə 83 Mb.
Pdf görüntüsü
səhifə74/82
tarix19.04.2023
ölçüsü83 Mb.
#106251
1   ...   70   71   72   73   74   75   76   77   ...   82
Java A Beginner’s Guide, Eighth Edition ( PDFDrive )

model corresponds to the state information associated with the component. For
example, in the case of a check box, the model contains a field that indicates if the box
is checked or unchecked. The view determines how the component is displayed on the
screen, including any aspects of the view that are affected by the current state of the
model. The controller determines how the component reacts to the user. For example,
when the user clicks a check box, the controller reacts by changing the model to reflect
the user’s choice (checked or unchecked). This then results in the view being updated.
By separating a component into a model, a view, and a controller, the specific
implementation of each can be changed without affecting the other two. For instance,
different view implementations can render the same component in different ways
without affecting the model or the controller.
Although the MVC architecture and the principles behind it are conceptually sound, the
high level of separation between the view and the controller was not beneficial for
Swing components. Instead, Swing uses a modified version of MVC that combines the
view and the controller into a single logical entity called the UI delegate. For this
reason, Swing’s approach is called either the model­delegate architecture or the
separable model architecture. Therefore, although Swing’s component architecture is
based on MVC, it does not use a classical implementation of it. Although you won’t
work directly with models or UI delegates in this chapter, they are, nevertheless,
present behind the scene.
As you work through this chapter, you will see that even though Swing embodies very
sophisticated design concepts, it is easy to use. In fact, one could argue that Swing’s


ease of use is its most important advantage. Simply stated, Swing makes manageable
the often difficult task of developing your program’s user interface. This lets you
concentrate on the GUI itself, rather than on implementation details.
Ask the Expert
Q
: You say that Swing defines a GUI that is superior to the AWT. Does
this mean that Swing replaces the AWT?
A
: No, Swing does not replace the AWT. Rather, Swing builds upon the
foundation provided by aspects of the AWT. Thus, portions of the AWT are still a
crucial part of Java. Although knowledge of the AWT is not required by this
chapter, you need a solid understanding of its structure and features if you seek full
Swing mastery.
COMPONENTS AND CONTAINERS
A Swing GUI consists of two key items: components and containers. However, this
distinction is mostly conceptual because all containers are also components. The
difference between the two is found in their intended purpose: As the term is
commonly used, a component is an independent visual control, such as a push button
or text field. A container holds a group of components. Thus, a container is a special
type of component that is designed to hold other components. Furthermore, in order
for a component to be displayed, it must be held within a container. Thus, all Swing
GUIs will have at least one container. Because containers are components, a container
can also hold other containers. This enables Swing to define what is called a
containment hierarchy, at the top of which must be a top­level container.
Components
In general, Swing components are derived from the JComponent class. (The only
exceptions to this are the four top­level containers, described in the next section.)
JComponent provides the functionality that is common to all components. For
example, JComponent supports the pluggable look and feel. JComponent inherits
the AWT classes Container and Component. Thus, a Swing component is built on
and compatible with an AWT component.


All of Swing’s components are represented by classes defined within the package
javax.swing. The following table shows the class names for Swing components
(including those used as containers):
Notice that all component classes begin with the letter J. For example, the class for a
label is JLabel, the class for a push button is JButton, and the class for a check box is
JCheckBox. This chapter introduces five commonly used components: JLabel,
JButton, JTextField, JCheckBox, and JList. Once you understand their basic
operation, it will be easy for you to learn to use the others.
Containers
Swing defines two types of containers. The first are top­level containers: JFrame,
JApplet, JWindow, and JDialog. (JApplet, which supports Swing­based applets,
has been deprecated since JDK 9.) These containers do not inherit JComponent.
They do, however, inherit the AWT classes Component and Container. Unlike
Swing’s other components, which are lightweight, the top­level containers are
heavyweight. This makes the top­level containers a special case in the Swing
component library.
As the name implies, a top­level container must be at the top of a containment
hierarchy. A top­level container is not contained within any other container.
Furthermore, every containment hierarchy must begin with a top­level container. The
one most commonly used for applications is JFrame.
The second type of container supported by Swing is the lightweight container.
Lightweight containers do inherit JComponent. Examples of lightweight containers


are JPanel, JScrollPane, and JRootPane. Lightweight containers are often used to
collectively organize and manage groups of related components because a lightweight
container can be contained within another container. Thus, you can use lightweight
containers to create subgroups of related controls that are contained within an outer
container.
The Top-Level Container Panes
Each top­level container defines a set of panes. At the top of the hierarchy is an
instance of JRootPane. JRootPane is a lightweight container whose purpose is to
manage the other panes. It also helps manage the optional menu bar. The panes that
compose the root pane are called the glass pane, the content pane, and the layered
pane.
The glass pane is the top­level pane. It sits above and completely covers all other panes.
The glass pane enables you to manage mouse events that affect the entire container
(rather than an individual control) or to paint over any other component, for example.
In most cases, you won’t need to use the glass pane directly. The layered pane allows
components to be given a depth value. This value determines which component
overlays another. (Thus, the layered pane lets you specify a Z­order for a component,
although this is not something that you will usually need to do.) The layered pane holds
the content pane and the (optional) menu bar. Although the glass pane and the layered
panes are integral to the operation of a top­level container and serve important
purposes, much of what they provide occurs behind the scene.
The pane with which your application will interact the most is the content pane,
because this is the pane to which you will add visual components. In other words, when
you add a component, such as a button, to a top­level container, you will add it to the
content pane. Therefore, the content pane holds the components that the user interacts
with.
LAYOUT MANAGERS
Before you begin writing a Swing program, there is one more thing that you need to be
aware of: the layout manager. The layout manager controls the position of components
within a container. Java offers several layout managers. Most are provided by the AWT
(within java.awt), but Swing adds a few of its own. All layout managers are instances
of a class that implements the LayoutManager interface. (Some will also implement
the LayoutManager2 interface.) Here is a list of a few of the layout managers


available to the Swing programmer:
Frankly, the topic of layout managers is quite large, and it is not possible to examine it
in detail in this book. Fortunately, this chapter uses only two layout managers
—BorderLayout and FlowLayout—and both are very easy to use.
BorderLayout is the default layout manager for the content pane. It implements a
layout style that defines five locations to which a component can be added. The first is
the center. The other four are the sides (i.e., borders), which are called north, south,
east, and west. By default, when you add a component to the content pane, you are
adding the component to the center. To add a component to one of the other regions,
specify its name.
Although a border layout is useful in some situations, often another, more flexible
layout manager is needed. One of the simplest is FlowLayout. A flow layout lays out
components one row at a time, top to bottom. When one row is full, layout advances to
the next row. Although this scheme gives you little control over the placement of
components, it is quite simple to use. However, be aware that if you resize the frame,
the position of the components will change.
A FIRST SIMPLE SWING PROGRAM
Swing programs differ from the console­based programs shown earlier in this book.
Not only do Swing programs use the Swing component set to handle user interaction,
but they also have special requirements that relate to threading. The best way to
understand the structure of a Swing program is to work through an example.
NOTE


The type of Swing programs shown in this chapter are desktop applications. In the past,
Swing was also used to create applets. However, applets have been deprecated by JDK 9
and are not recommended for new code. For this reason, they are not discussed in this
book.
Although quite short, the following program shows one way to write a Swing
application. In the process it demonstrates several key features of Swing. It uses two
Swing components: JFrame and JLabel. JFrame is the top­level container that is
commonly used for Swing applications. JLabel is the Swing component that creates a
label, which is a component that displays information. The label is Swing’s simplest
component because it is passive. That is, a label does not respond to user input. It just
displays output. The program uses a JFrame container to hold an instance of a
JLabel. The label displays a short text message.


Swing programs are compiled and run in the same way as other Java applications.
Thus, to compile this program, you can use this command line:
To run the program, use this command line:
When the program is run, it will produce the window shown in 
Figure 16­1
.
Figure 16­1 The window produced by the SwingDemo program
The First Swing Example Line by Line
Because the SwingDemo program illustrates several key Swing concepts, we will
examine it carefully, line by line. The program begins by importing the following
package:
This javax.swing package contains the components and models defined by Swing. For
example, it defines classes that implement labels, buttons, edit controls, and menus.
This package will be included in all programs that use Swing. Beginning with JDK 9,
javax.swing is in the java.desktop module.
Next, the program declares the SwingDemo class and a constructor for that class. The
constructor is where most of the action of the program occurs. It begins by creating a
JFrame, using this line of code:
This creates a container called jfrm that defines a rectangular window complete with a
title bar; close, minimize, maximize, and restore buttons; and a system menu. Thus, it
creates a standard, top­level window. The title of the window is passed to the
constructor.


Next, the window is sized using this statement:
The setSize( ) method sets the dimensions of the window, which are specified in
pixels. Its general form is shown here:
void setSize(int width, int height)
In this example, the width of the window is set to 275 and the height is set to 100.
By default, when a top­level window is closed (such as when the user clicks the close
box), the window is removed from the screen, but the application is not terminated.
While this default behavior is useful in some situations, it is not what is needed for
most applications. Instead, you will usually want the entire application to terminate
when its top­level window is closed. There are a couple of ways to achieve this. The
easiest way is to call setDefaultCloseOperation( ), as the program does:
After this call executes, closing the window causes the entire application to terminate.
The general form of setDefaultCloseOperation( ) is shown here:
void setDefaultCloseOperation(int what)
The value passed in what determines what happens when the window is closed. There
are several other options in addition to JFrame.EXIT_ON_CLOSE. They are shown
here:
JFrame.DISPOSE_ON_CLOSE
JFrame.HIDE_ON_CLOSE
JFrame.DO_NOTHING_ON_CLOSE
Their names reflect their actions. These constants are declared in WindowConstants,
which is an interface declared in javax.swing that is implemented by JFrame.
The next line of code creates a JLabel component:
JLabel is the easiest­to­use Swing component because it does not accept user input. It


simply displays information, which can consist of text, an icon, or a combination of the
two. The label created by the program contains only text, which is passed to its
constructor.
The next line of code adds the label to the content pane of the frame:
As explained earlier, all top­level containers have a content pane in which components
are stored. Thus, to add a component to a frame, you must add it to the frame’s content
pane. This is accomplished by calling add( ) on the JFrame reference (jfrm in this
case). The add( ) method has several versions. The general form of the one used by the
program is shown here:
Component add(Component comp)
By default, the content pane associated with a JFrame uses a border layout. This
version of add( ) adds the component (in this case, a label) to the center location.
Other versions of add( ) enable you to specify one of the border regions. When a
component is added to the center, its size is automatically adjusted to fit the size of the
center.
The last statement in the SwingDemo constructor causes the window to become
visible.
The setVisible( ) method has this general form:
void setVisible(boolean flag)
If flag is true, the window will be displayed. Otherwise, it will be hidden. By default, a
JFrame is invisible, so setVisible(true) must be called to show it.
Inside main( ), a SwingDemo object is created, which causes the window and the
label to be displayed. Notice that the SwingDemo constructor is invoked using these
lines of code:


This sequence causes a SwingDemo object to be created on the event­dispatching
thread rather than on the main thread of the application. Here’s why. In general, Swing
programs are event­driven. For example, when a user interacts with a component, an
event is generated. An event is passed to the application by calling an event handler
defined by the application. However, the handler is executed on the event­dispatching
thread provided by Swing and not on the main thread of the application. Thus,
although event handlers are defined by your program, they are called on a thread that
was not created by your program. To avoid problems (such as two different threads
trying to update the same component at the same time), all Swing GUI components
must be created and updated from the event­dispatching thread, not the main thread of
the application. However, main( ) is executed on the main thread. Thus, it cannot
directly instantiate a SwingDemo object. Instead, it must create a Runnable object
that executes on the event­dispatching thread, and have this object create the GUI.
To enable the GUI code to be created on the event­dispatching thread, you must use
one of two methods that are defined by the SwingUtilities class. These methods are
invokeLater( ) and invokeAndWait( ). They are shown here:
static void invokeLater(Runnable obj)
static void invokeAndWait(Runnable obj)
throws InterruptedException, InvocationTargetException
Here, obj is a Runnable object that will have its run( ) method called by the event­
dispatching thread. The difference between the two methods is that invokeLater( )
returns immediately, but invokeAndWait( ) waits until obj.run( ) returns. You can
use these methods to call a method that constructs the GUI for your Swing application,
or whenever you need to modify the state of the GUI from code not executed by the
event­dispatching thread. For the types of programs shown in this chapter, you will
normally want to use invokeLater( ), as the preceding program does.
One more point: The preceding program does not respond to any events, because
JLabel is a passive component. In other words, a JLabel does not generate any
events. Therefore, the preceding program does not include any event handlers.
However, all other components generate events to which your program must respond,


as the subsequent examples in this chapter show.
Ask the Expert
Q
: You state that it is possible to add a component to the other regions
of a border layout by using an overloaded version of add( ). Can you
explain?
A
: As explained, BorderLayout implements a layout style that defines five
locations to which a component can be added. The first is the center. The other
four are the sides (i.e., borders), which are called north, south, east, and west. By
default, when you add a component to the content pane, you are adding the
component to the center. To specify one of the other locations, use this form of
add( ):
void add(Component comp, Object loc)
Here, comp is the component to add and loc specifies the location to which it is
added. The loc value is typically one of the following:
In general, BorderLayout is most useful when you are creating a JFrame that
contains a centered component (which might be a group of components held
within one of Swing’s lightweight containers) that has a header and/or footer
component associated with it. In other situations, one of Java’s other layout
managers will be more appropriate.
SWING EVENT HANDLING
As just explained, in general, Swing programs are event driven, with components
interacting with the program through events. For example, an event is generated when
the user clicks a button, moves the mouse, types a key, or selects an item from a list.
Events can also be generated in other ways. For example, an event is generated when a
timer goes off. When an event is sent to a program, the program responds to the event
by use of an event handler. Thus, event handling is an important part of nearly all


Swing applications.
The event handling mechanism used by Swing is called the delegation event model. Its
concept is quite simple. An event source generates an event and sends it to one or more

Yüklə 83 Mb.

Dostları ilə paylaş:
1   ...   70   71   72   73   74   75   76   77   ...   82




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©genderi.org 2024
rəhbərliyinə müraciət

    Ana səhifə