You are on page 1of 12

Advanced Swing

Swings
Swing is a widget toolkit for Java. It is part of Sun Microsystems' Java
Foundation Classes (JFC) an API for providing a graphical user
interface (GUI) for Java programs.

Swing was developed to provide a more sophisticated set of


GUI components than the earlier Abstract Window Toolkit. Swing provides a
native look and feel that emulates the look and feel of several platforms, and
also supports a pluggable look and feel that allows applications to have a look
and feel unrelated to the underlying platform.

Swing is a platform-independent, Model-View-Controller GUI framework for


Java. It follows a single-threaded programming model, and possesses the
following traits:
Features:
Platform independence
Swing is platform independent both in terms of its expression (Java) and its
implementation (non-native universal rendering of widgets).
Extensibility
Swing is a highly partitioned architecture, which allows for the "plugging" of
various custom implementations of specified framework interfaces: Users can
provide their own custom implementation(s) of these components to override
the default implementations. In general, Swing users can extend the framework
by extending existing (framework) classes and/or providing alternative
implementations of core components.
Component-oriented
Swing is a component-based framework. The distinction between objects and
components is a fairly subtle point: concisely, a component is a well-behaved
object with a known/specified characteristic pattern of behavior. Swing objects
asynchronously fire events, have "bound" properties, and respond to a well-
known set of commands (specific to the component.) Specifically, Swing
components are Java Beans components, compliant with the Java Beans
Component Architecture specifications.

WWW.ThesisScientist.com
Customizable
Given the programmatic rendering model of the Swing framework, fine control
over the details of rendering of a component is possible in Swing. As a general
pattern, the visual representation of a Swing component is a composition of a
standard set of elements, such as a "border", "inset", decorations, etc.
Typically, users will programmatically customize a standard Swing component
(such as a JTable) by assigning specific Borders, Colors, Backgrounds,
opacities, etc., as the properties of that component. The core component will
then use this property (settings) to determine the appropriate renderers to use
in painting its various aspects. However, it is also completely possible to create
unique GUI controls with highly customized visual representation.
Configurable
Swing's heavy reliance on runtime mechanisms and indirect composition
patterns allows it to respond at runtime to fundamental changes in its settings.
For example, a Swing-based application can change its look and feel at
runtime. Further, users can provide their own look and feel implementation,
which allows for uniform changes in the look and feel of existing Swing
applications without any programmatic change to the application code.
Lightweight UI
Swing's configurability is a result of a choice not to use the native host OS's
GUI controls for displaying itself. Swing "paints" its controls programmatically
through the use of Java 2D APIs, rather than calling into a native user
interface toolkit. Thus, a Swing component does not have a corresponding
native OS GUI component, and is free to render itself in any way that is
possible with the underlying graphics APIs.

However, at its core every Swing component relies on an AWT container, since
(Swing's) JComponent extends (AWT's) Container. This allows Swing to plug
into the host OS's GUI management framework, including the crucial
device/screen mappings and user interactions, such as key presses or mouse
movements. Swing simply "transposes" its own (OS agnostic) semantics over
the underlying (OS specific) components. So, for example, every Swing
component paints its rendition on the graphic device in response to a call to
component.paint(), which is defined in (AWT) Container. But unlike AWT

WWW.ThesisScientist.com
components, which delegated the painting to their OS-native "heavyweight"
widget, Swing components are responsible for their own rendering.

This transposition and decoupling is not merely visual, and extends to Swing's
management and application of its own OS-independent semantics for events
fired within its component containment hierarchies. Generally speaking, the
Swing Architecture delegates the task of mapping the various flavors of OS GUI
semantics onto a simple, but generalized, pattern to the AWT container.
Building on that generalized platform, it establishes its own rich and complex
GUI semantics in the form of the JComponent model. A review of the source of
Container java and JComponent java classes is recommended for further
insights into the nature of the interface between Swing's lightweight
components and AWT's heavyweight widgets.
Loosely-Coupled/MVC
The Swing library makes heavy use of
the Model/View/Controller software design pattern, which conceptually
decouples the data being viewed from the user interface controls through which
it is viewed. Because of this, most Swing components have
associated models (which are specified in terms of Java interfaces), and the
programmer can use various default implementations or provide their own. The
framework provides default implementations of model interfaces for all of its
concrete components.

Typically, Swing component model objects are responsible for providing a


concise interface defining events fired, and accessible properties for the
(conceptual) data model for use by the associated JComponent. Given that the
overall MVC pattern is a loosely-coupled collaborative object relationship
pattern, the model provides the programmatic means for attaching event
listeners to the data model object. Typically, these events are model centric (ex:
a "row inserted" event in a table model) and are mapped by the JComponent
specialization into a meaningful event for the GUI component.

For example, the JTable has a model called TableModel that describes an
interface for how a table would access tabular data. A default implementation
of this operates on a two-dimensional array.

The view component of a Swing JComponent is the object used to graphically


"represent" the conceptual GUI control. A distinction of Swing, as a GUI

WWW.ThesisScientist.com
framework, is in its reliance on programmatically-rendered GUI controls (as
opposed to the use of the native host OS's GUI controls). Prior to Java 6 Update
10, this distinction was a source of complications when mixing AWT controls,
which use native controls, with Swing controls in a GUI.

Finally, in terms of visual composition and management, Swing favors relative


layouts (which specify the positional relationships between components) as
opposed to absolute layouts (which specify the exact location and size of
components). This bias towards "fluid"' visual ordering is due to its origins in
the applet operating environment that framed the design and development of
the original Java GUI toolkit. (Conceptually, this view of the layout
management is quite similar to that which informs the rendering of HTML
content in browsers, and addresses the same set of concerns that motivated
the former.)
Look and feel
Swing allows one to specialize the look and feel of widgets, by modifying the
default (via runtime parameters), deriving from an existing one, by creating one
from scratch, or, beginning withJ2SE 5.0, by using the skinnable synth Look
and Feel, which is configured with an XML property file. The look and feel can
be changed at runtime, and early demonstrations of Swing frequently provided
a way to do this.

Lists

If you want to present a set of choices to a user, and a radio button or


checkbox set consumes too much space, you can use a combo box or a list.
The JList component has many more features, and its design is similar to that
of the tree and table components. The list control is somewhat awkward to use
for common cases because you need to manipulate some of the machinery that
makes the general cases possible.

The JList Component

The JList component is similar to a set of checkboxes or radio buttons, except


that the items are placed inside a single box and are selected by clicking on the
items themselves, not on buttons. If you permit multiple selections for a list
box, the user can select any combination of the items in the box.
WWW.ThesisScientist.com
To construct this list component, you first start out with an array of strings,
then pass the array to the JList constructor :

String[ ] words= { "quick", "brown", "hungry", "wild", ... };


JList wordList= newJList(words);

List boxes do not scroll automatically. To make a list box scroll, you must
insert it into a scroll pane:

JScrollPane scroll Pane=new JScrollPane(wordList);

You then add the scroll pane, not the list, into the surrounding panel. By
default, the list component displays eight items; use the setVisibleRowCount
method to change that value:

wordList.setVisibleRowCount(4); // displays 4 items

You can set the layout orientation to one of three values:


JList.VERTICAL (the default): arrange all items vertically.
List.VERTICAL_WRAP: start new columns if there are more items than
the visible row count.
List.HORIZONTAL_WRAP: start new columns if there are more items
than the visible row count, but fill them horizontally.

You can also restrict the user to a more limited selection mode with the
setSelectionMode method:

wordList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
/ / select one item at a time

wordList.setSelectionModel(ListSelectionModel.SINGLE_INTERVAL_SELECTlON);
/ / select one item or one range of items

The basic user interface components send out action events when the user
activates them. So u need to add a list selection listener to the list component,
and implement the method

public void valueChanged(ListSelectionEvent evt)

in the listener. When the user selects items, a flurry of list selection events is
generated.

Once you are notified that an event has happened, you will want to find out
what items are currently selected. The getSelectedValues method returns an

WWW.ThesisScientist.com
array of objects containing all selected items. Cast each array element to a
string.

Object[ ] values =list.getSelectedValues();


for(Object value : values)
do something with (String) value;

List Models
The most common method for using a list component.
Specify a fixed set of strings for display in the list.
Place the list inside a scroll pane, and
Trap the list selection events.

The JList class is responsible for the visual appearance of the data. It actually
knows very little about how the data are stored-all it knows is that it can
retrieve the data through some object that implements the ListModel interface:

public interface ListModel


{
int getSize () ;
Object getElementAt( int i) ;
void addListDataListener(ListDataListener l) ;
void removeListDataListener(ListDataListener l):
}
Through this interface, the JList can get a count of elements and retrieve each
one of the elements.

WWW.ThesisScientist.com
Also, the JList object can add itself as a list data listener. That way, if the
collection of elements changes, JList gets notified so that it can repaint the list.
Adding and removing listeners, has been done in the AbstractListModel class,
which we extend. We only need to supply the getSize and getElementAt
methods:

class WordListModel extends AbstractListModel


{
public WordListModel(int n)
{
length = n;
}
public int getSize()
{
return (int) Math.pow(26,length);
}
public Object getElementAt(int n)
{
II compute nth string
}

(draw diagram on page no 349)

Inserting and Removing Values

You cannot directly edit the collection of list values. Instead, you must access
the model and then add or remove elements. Suppose you want to add more
values to a list. You can obtain a reference to the model:

ListModel model=list.getModel() ;

But the ListModel interface also has no methods to insert or remove elements
because a list model is that it need not store the elements.

Instead, you should construct a DefaultListModel object, fill it with the initial
values, and associate it with the list.

DefaultListModel model = new DefaultListModel() ;


model.addElement("quick");
model.addElement("brown");

JList list = newJList(model) ;

WWW.ThesisScientist.com
Now you can add or remove values from the model object. The model object
then notifies the list of the changes, and the list repaints itself.
model.removeElement( "quick");
model.addElement("slow") ;

Rendering Values

You can easily represent your list values with any drawing whatsoever.

Although the JList class can display strings and icons automatically, you need
to install a list cell renderer into the JList object for all custom drawing. A list
cell renderer is any class that implements the following interface:

interface ListCellRenderer
{
Component getListCellRendererComponent(JList list,
Object value, int index, boolean isSelected, boolean cell HasFocus) ;
}

This method is called for each cell. It returns a component that paints the cell
contents. The component is placed at the appropriate location whenever a cell
needs to be rendered.
If the rendered image just contains text, an icon, and possibly a change of
color, then you can get by with configuring a JLabel.For eg, to show the font
name in its own font, we can use the following renderer:

class FontCellRenderer extends JLabel implements ListCellRenderer


{
public Component getListCellRendererComponent(JList list, Object value, int
index, boolean isSelected, Boolean cellHasFocus)
{
JLabel label = new JLabel() ;
Font font = (Font) value ;
setText(font.getFamily()) ;
setFont(font) ;
setOpaque(true) ;
setBackground(isSelected?list.getSelectionBackground():list.getBackground());
setForeground(isSelected?list.getSelectionForeground():list.getForeground());
return this ;
}
}

TREES

WWW.ThesisScientist.com
Many tree structures arise in everyday life,such as the hierarchy of countries ,states & cities.The Swing
library has a JTree class for this purpose.The JTree class takes care of laying out the tree and processing
user requests for expanding and collapsing nodes. A tree is composed of nodes.Every node is either a leaf
or it has child nodes.Everynode,with the exception of the root node, has exactly one parent.A tree has
exactly one root node. Sometimes you have a collection of trees, each of which has its own root node.Such
a collection is called a forest.

(draw diagram on page no 358 Fig 6.7 )

Simple Trees -

The JTree component follows the model view-controller pattern. You provide a model of the hierarchical
data, and the component displays it for you. To construct a JTree, you supply the tree model in the
constructor TreeModel model=. . . JTreee tree = new JTree(model) ;

To construct a default tree model, you must supply a root node.


TreeNode root = . . . DefaultTreeModel model= newDefaultTreeModel(root) ;

TreeNode is another interface.


you can simply pass the root node to the JTree constructor.
Then the tree automatically constructs a default tree model :
JTree tree =new JTree(root) ;

Editing Trees and Tree Paths -


The JTree class has a surprising way of identifying nodes in a tree. It doesnot deal with tree nodes, but
with paths of objects,called tree paths. A tree path starts at the root & consists of a sequence of child
nodes.

(draw diagram on page no 366 Fig 6-18)

The JTree class knows nothing about the TreeNode interface.That interace is never used by the TreeModel
interface.it is only used by the DefaultTreeModel implementation.You can have other tree models in which
the nodes do not implement the TreeNode interface at all.If you use a tree model that manages other types
of objects, then those objects may not have getParent & getChild methods. The TreePath class manages a
sequence of Object references.
A number of JTree methods return Treepath objects.When you have a tree path,you usually just need to
Know the terminal node,which you get with the getLastPathComponent method.For eg, to find out the
currently selected node in a tree, you use the getSelectionPath method of the JTree
class.You get a TreePath object back, from which you can retrieve the actual node.

TreePath selectionPath= tree.getSelectionPath() ;


DefaultMutableTreeNode selectedNode =
(DefaultMutableTreeNode)
selectionPath.getLastPathComponent() ;

If you use the insertNodeInto method of the DefaultTreeModel class, the model class takes care of that. For
eg, the following call appends a new node as the last child of the selected node & notifies the tree view.
WWW.ThesisScientist.com
model.insertNodelnto(newNode, selectedNode ,
selectedNode.getchildCount()) ;
The analogous call removeNodeFromParent removes a node and notifies the view:
model.removeNodeFromParent (selectedNode) ;

Node Enumeration -

Sometimes you need to find a node in a tree by starting at the root & visiting all children until you have
found a match.The DefaultMutableTreeNode class has several methods for iterating through nodes. The
breadthFirstEnumeration & depthFirstEnumeration methods return enumeration objects whose
nextElement method visits all children of the current node,using either a breadth-first or depth-first
traversal. Breadth-first enumeration is the easiest to visualize.The tree is traversed in layers.The root is
visited first,followed by all of its children, then followed by the grandchildren, and so on.To visualize depth-
first enumeration,imagine a rat trapped in a tree-shaped maze. It rushes along the first path until it comes to
a leaf.Then, it backtracks and turns around to the next path, and so on. The postOrderTraversal method is
a synonym for depthFirstTraversal because the search process visits the childen before visiting the
parents.
Here is the typical usage pattern:

Enumeration breadthFirst = node.breadthFirstEnumeration() ;


while (breadthFirst.hasMoreElements())
do something with breadthFirst. nextElement();
Finally,a method, pathFromAncestorEnumeration, finds a path from an ancestor to a given node and then
enumerates the nodes along that path.

Rendering Nodes-
you will often need to change the way in which a tree component draws the nodes.The most common
change is to choose different icons for nodes and leaves.Other changes might involve changing the font of
the node labels or drawing images at the nodes. All these changes are made possible by installing a new
tree cell renderer into the tree.By default, the JTree class uses DefaultTreeCellRenderer objects to draw
each node.The DefaultTreeCellRenderer class extends the JLabelclass. The label contains the node icon
and the node label.

You can customize the display in three ways :


1. You can change the icons, font, and background color used
by a DefaultTreeCellRenderer.These settings are used for
all nodes in the tree.
2. You can install a renderer that extends the
DefaultTreeCellRenderer class and vary the icons, fonts,
and background color for each node.
3. You can install a renderer that implements the
TreeCellRenderer interface, to draw a custom
image for each node.
To change the appearance of individual nodes,you install a tree cell renderer.The TreeCellRenderer
interface has a single method:
Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected,
boolean expanded, boolean leaf, int row, boolean hasFocus)
WWW.ThesisScientist.com
Custom Tree Models -

The TreeModel interface has only a handful of methods.The first group of methods enables the JTree to
find the tree nodes by first getting the root, then the children.The JTree class calls these methods only
when the user actually expands a node.
Object getRoot ()
int getChildCount(Object parent)
Object getChild(Object parent, int index)

TheTreeModel is responsible for telling the JTree how they are connected.The next method of the
TreeModel interface is the reverse of getChild:
int getlndexOfChild(Object parent,Object child)

The tree model tells the JTree which nodes should be displayed as leaves:
boolean isLeaf(Object node)
If your code changes the tree model, then the tree needs to be notified so that it can redraw itself. The tree
adds itself as a TreeModelListener to the model.Thus, the model must support the usual listener
management methods:
void addTreeModelListener(TreeModelListener l)
void removeTreeModelListener(TreeModelListener l)

When the model modifies the tree contents, it calls one of the four methods of the TreeModelListener
interface:
void treeNodesChanged(TreeModelEvent e)
void treeNodeslnserted(TreeModelEvent e)
void treeNodesRemoved (TreeModelEvent e )
void treeStructureChanged(TreeModelEvent e)

The TreeModelEvent object describes the location of the change.


Finally if the user edits a tree node, your model is called with the change.
Void valueForPathChanged(TreePath path ,Object newValue)
If you dont allow editing, this method is never called.

Progress Indicators -

A JProgressBar is a Swing component that indicates progress. A ProgressMonitor is a dialog box that
contains a progress bar. A ProqressMonitorInputStream displays a progress monitor
dialog box while the stream is read.

Progress Bars
A progressbar is a simple component-just a rectangle that is partially filled with color to indicate the
progress of an operation. By default, progress is indicated by a string n% .
You construct a progress bar much as you construct a slider, by supplying the minimum and maximum
value and an optional orientation:
progressBar = newJProgressBar(0, 1000);
progressBar= newJProgressBar(SwingConstants. VERTICAL, 0, 1000);
WWW.ThesisScientist.com
You can also set the minimum and maximum with the setMinimum and setMaximum methods.
Unlike a slider,the progress bar cannot be adjusted by the user. Your program needs to call setValueto
update it.
If you call
progressBar. setStringPainted(true);
the progress bar computes the completion percentage and displays a string n% .If you want to show a
different string, you can supply it with the setString method:
if (progressBar.getValue() > 900)
progressBar.setString(" AlmostDone ");

Progress Monitor

A ProgressMonitor is a complete dialog box that contains a progress bar.The dialog box contains a Cancel
button.If you click it,the monitor dialog box is closed.In addition,your program can query whether the user
has canceled the dialog box & terminate the monitored action.
You construct a progress monitor by supplying the following:
The parent component over which the dialog box should pop up.
An object that is displayed on the dialog box.
An optional note to display below the object.
The minimum and maximum values. .
As you update the progress value, you should also call the isCanceled method to see if the program user
has clicked the
Cancel button.

When the monitored activity has concluded, call the close method to dismiss the dialog box.You can reuse
the same dialog box by calling start again.
There are two conditions for termination. The activity might have completed, or the user might have
canceled it. In each of these cases, we close down :
The timer that monitored the activity.
The progress dialog box.
The activity itself (by interrupting the thread).

Component Organizers

These include the split pane, a mechanism for splitting an area into multiple parts whose boundaries canbe
adjusted,the tabbed pane,which uses tab dividers to allow a user to flip through multiple panels,& the
desktop pane.,which can be used to implement applications that display multiple internal frames.

WWW.ThesisScientist.com

You might also like