You are on page 1of 28

Java Swing

Java Swing
Programming
Programming
Kyle Brown
Kyle Brown
IBM WebSphere Services
IBM WebSphere Services
Overview Overview
Swings Architecture & background
Swings Architecture & background
Basic Swing Programming
Basic Swing Programming
Swing lists
Swing lists
Swing tables
Swing tables
Swing trees
Swing trees
What's Swing? What's Swing?
Swing is Suns alternate Windowing
Swing is Suns alternate Windowing
Framework
Framework
Part of the JFC (Java Foundation
Part of the JFC (Java Foundation
Classes)
Classes)
Standard part of Java 2
Standard part of Java 2
A full replacement/alternative to AWT
A full replacement/alternative to AWT
Found in packages starting with
Found in packages starting with
javax.swing
javax.swing
Key Features of Swing Key Features of Swing
Not based on windowing system
Not based on windowing system
all Swing components are lightweight
all Swing components are lightweight
Pluggable Look and Feel (PLAF)
Pluggable Look and Feel (PLAF)
Richer component set than AWT
Richer component set than AWT
Doesnt take the least common
Doesnt take the least common
denominator approach
denominator approach
includes components not found in *any*
includes components not found in *any*
windowing system
windowing system
adds functionality to components that
adds functionality to components that
already have counterparts in the AWT
already have counterparts in the AWT
Using Swing Using Swing
Swing should not be combined with
Swing should not be combined with
AWT
AWT
Each Window should be fully Swing or
Each Window should be fully Swing or
fully AWT
fully AWT
Since Swing matches the AWTs
Since Swing matches the AWTs
functionality, thats not hard
functionality, thats not hard
Most Swing components are
Most Swing components are
upwards-compatible with their AWT
upwards-compatible with their AWT
counterparts
counterparts
easy to change code from AWT to Swing
easy to change code from AWT to Swing
Swing Architecture Swing Architecture
Swing follows the
Swing follows the
MVC paradigm
MVC paradigm
for building user
for building user
interfaces
interfaces
Each UI
Each UI
Component has a
Component has a
model
model
We will often
We will often
customize certain
customize certain
Swing models
Swing models
data change
change
notification
data access
gestures
and
events
View Controller
Model
Basic Swing Programming Basic Swing Programming
As noted previously, Swing adds an
As noted previously, Swing adds an
entirely new set of components to Java
entirely new set of components to Java
Upward-compatible with their AWT
Upward-compatible with their AWT
counterparts
counterparts
We wont deeply cover those similar to
We wont deeply cover those similar to
their AWT counterparts
their AWT counterparts
We will start at the bottom
We will start at the bottom
JFrame
JFrame
Japplet
Japplet
Top-level hierarchy Top-level hierarchy
Each top-level
Each top-level
class adds new
class adds new
behavior to
behavior to
existing AWT
existing AWT
components
components
Frame
JFrame
Dialog
JDialog
Applet
JApplet
Window
Comparing Swing & AWT Comparing Swing & AWT
import java.awt.*;
public class ExampleAWTFrame extends java.awt.Frame {
public ExampleAWTFrame ( ) {
super();
Panel aPanel = new Panel();
aPanel.setLayout(new BorderLayout());
add(aPanel);
Label hello = new Label("Hello World");
aPanel.add(hello, BorderLayout.NORTH);
}
public static void main(String args[]) {
ExampleAWTFrame aFrame = new ExampleAWTFrame();
aFrame.setVisible(true);
}}
Comparing Swing & AWT Comparing Swing & AWT
import java.awt.*;
import com.sun.java.swing.*;
public class ExampleSwingJFrame extends com.sun.java.swing.JFrame {
public ExampleSwingJFrame() {
super();
JPanel aPanel = new JPanel();
aPanel.setLayout(new BorderLayout());
getContentPane().add(aPanel);
JLabel hello = new JLabel("Hello World");
aPanel.add(hello, BorderLayout.NORTH);
}
public static void main(String args[]) {
ExampleSwingJFrame aFrame = new ExampleSwingJFrame();
aFrame.setVisible(true);
}}
JFrames JFrames
A JFrame acts like an AWT Frame
A JFrame acts like an AWT Frame
Except it handles Swing component
Except it handles Swing component
nesting
nesting
A JFrame is really two panes
A JFrame is really two panes
A LayeredPane that has an optional
A LayeredPane that has an optional
menu bar and a content pane
menu bar and a content pane
A GlassPane that sits transparently in
A GlassPane that sits transparently in
front of the LayeredPane
front of the LayeredPane
Partial Swing Hierarchy Partial Swing Hierarchy
JComponent
AbstractButton
JButton JToggleButton JMenuItem
JComboBox JPanel JLabel JList JSlider JTree JTable
JTabbedPane JScrollPane
Container
Borders Borders
Any JComponent can have a Border
Any JComponent can have a Border
placed on it
placed on it
Usually only used on JPanels
Usually only used on JPanels
Specify the border with
Specify the border with
aJComponent.setBorder(Border aBorder)
aJComponent.setBorder(Border aBorder)
Common Borders include BevelBorder,
Common Borders include BevelBorder,
TitledBorder
TitledBorder
Normally built with a BorderFactory
Normally built with a BorderFactory
JTitledBorder Example JTitledBorder Example
public ExampleWithGroupBox ( ) {
super();
JPanel aPanel = new JPanel();
aPanel.setLayout(new BorderLayout());
TitledBorder border =
BorderFactory.createTitledBorder(BorderFactory.createBevelBorder(2), "Group");
aPanel.setBorder(border);
getContentPane().add(aPanel);
JLabel hello = new JLabel("Hello World");
aPanel.add(hello, BorderLayout.CENTER);
}
JTabbedPane JTabbedPane
A JTabbedPane represents a notebook
A JTabbedPane represents a notebook
Any JComponent can be a page in a
Any JComponent can be a page in a
JTabbedPane
JTabbedPane
JPanels are usually used
JPanels are usually used
Tabs can be added, inserted at runtime,
Tabs can be added, inserted at runtime,
deleted and selected
deleted and selected
Creating Tabs Creating Tabs
public ExampleWithTabbedPane ( ) {
super();
JTabbedPane tabs = new JTabbedPane();
tabs.addTab("Page1", buildTabOne());
tabs.addTab("Page2", buildTabTwo());
tabs.addTab("Page3", buildTabThree());
getContentPane().add(tabs);
}
public JPanel buildTabOne() {
JPanel aPanel = new JPanel();
JLabel first = new JLabel("This is the first tab");
aPanel.add(first, BorderLayout.CENTER);
return aPanel;
}
JTabbedPane Details JTabbedPane Details
Tabs are indexed from 0
Tabs are indexed from 0
JTabbedPane.getTabCount();
JTabbedPane.getTabCount();
Can remove tabs with
Can remove tabs with
JTabbedPane.removeTabAt(index);
JTabbedPane.removeTabAt(index);
Can select a tab with
Can select a tab with
JTabbedPane.setSelectedIndex(index)
JTabbedPane.setSelectedIndex(index)
JTabbedPane Events JTabbedPane Events
The JTabbedPane supports the
The JTabbedPane supports the
ChangedEvent notification
ChangedEvent notification
Clients must implement the
Clients must implement the
ChangeListener interface
ChangeListener interface
void stateChanged(ChangeEvent e)
void stateChanged(ChangeEvent e)
No state information is passed in
No state information is passed in
query the source for the new state
query the source for the new state
JScrollPane JScrollPane
A JScrollPane manages scrolling over a A JScrollPane manages scrolling over a
larger view
larger view
It manages a viewport on the view
It manages a viewport on the view
Viewport
View
JScrollPane example JScrollPane example
/*
* Add a Scroll pane to the Jframe. Put a JLabel having
* the numbers 0 - 49 into the scrollPanes viewport
*
*/
public ExampleScrolling ( ) {
super();
JScrollPane scroller = new JScrollPane();
getContentPane().add(scroller);
StringBuffer bigBuffer = new StringBuffer();
for (int i=0; i<50; i++) {
bigBuffer.append(Integer.toString(i));
bigBuffer.append(' ');
}
JLabel longLabel = new JLabel(bigBuffer.toString());
scroller.getViewport().add(longLabel);
}
Scrollable Interface Scrollable Interface
Components that will be scrolled by a
Components that will be scrolled by a
JScrollPane should implement the
JScrollPane should implement the
Interface Scrollable
Interface Scrollable
Most Swing components implement this
Most Swing components implement this
already
already
This Interface defines methods to
This Interface defines methods to
return the preferred size of the viewport
return the preferred size of the viewport
get the increment in pixels to scroll by unit
get the increment in pixels to scroll by unit
and block
and block
JSplitPane JSplitPane
A JSplitPane is a splitter pane that
A JSplitPane is a splitter pane that
allows the user to resize two components
allows the user to resize two components
dynamically
dynamically
Can split horizontally or vertically
Can split horizontally or vertically
Use the constant
Use the constant
JSplitPane.VERTICAL_SPLIT or
JSplitPane.VERTICAL_SPLIT or
JSplitPane.HORIZONTAL_SPLIT in
JSplitPane.HORIZONTAL_SPLIT in
the constructor
the constructor
JSplitPane Example JSplitPane Example
public ExampleWithSplitPane ( ) {
JSplitPane splitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
splitter.setLeftComponent(new JTextArea());
splitter.setRightComponent(new JTextArea());
getContentPane().add(splitter);
}
public static void main(String args[]) {
ExampleWithSplitPane example = new ExampleWithSplitPane();
example.pack();
example.setVisible(true);
}
JProgressBar JProgressBar
A JProgressBar is a standard
A JProgressBar is a standard
Windows-like progress indicator
Windows-like progress indicator
LED-like display like a Stereo system
LED-like display like a Stereo system
It is usually used in its own Frame or
It is usually used in its own Frame or
dialog
dialog
Often combined with one or more labels Often combined with one or more labels
JSlider JSlider
A JSlider is a volume-control slider
A JSlider is a volume-control slider
component
component
Familiar in many Windows applications
Familiar in many Windows applications
Jsliders have a variety of attributes
Jsliders have a variety of attributes
Major and Minor Ticks
Major and Minor Ticks
Labels
Labels
Minimum & Maximum values
Minimum & Maximum values
Clients watch for the ChangeEvent
Clients watch for the ChangeEvent
notification
notification
Similar to JTabbedPane
Similar to JTabbedPane
JSlider Example JSlider Example
public ExampleWithSlider ( ) {
JPanel aPanel = new JPanel();
aPanel.setLayout(new BorderLayout());
getContentPane().add(aPanel);
counterLabel = new JLabel("0");
aPanel.add(counterLabel, BorderLayout.SOUTH);
JSlider slider = new
JSlider(SwingConstants.HORIZONTAL, 0, 100, 0);
slider.setMajorTickSpacing(20);
slider.setMinorTickSpacing(10);
slider.setPaintTicks(true);
slider.setPaintLabels(true);

slider.addChangeListener(this);
aPanel.add(slider, BorderLayout.NORTH);
}
public void stateChanged(ChangeEvent e) {
int value = ((JSlider) e.getSource()).getValue();
counterLabel.setText(Integer.toString(value));
}
AbstractButton Hierarchy AbstractButton Hierarchy
Swing has a number of
Swing has a number of
button components
button components
push buttons, radio
push buttons, radio
buttons, check boxes
buttons, check boxes
Usually each will use an
Usually each will use an
ActionListener to hook
ActionListener to hook
into UI actions
into UI actions
actionPerformed( )
AbstractButton
ActionListener
<<interface>>
JButton JToggleButton
JCheckBox JRadioButton
JButton Example JButton Example
public ExampleJButton() {
super();
JPanel aPanel = new JPanel();
aPanel.setLayout(new BorderLayout());
getContentPane().add(aPanel);
JButton push =new JButton("Push Me");
push.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
buttonPushed();
}
});
aPanel.add(push, BorderLayout.NORTH);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public void buttonPushed() {
System.out.println("The button was pushed");
}
JMenu Hierarchy JMenu Hierarchy
Swing Menus are similar
Swing Menus are similar
to Buttons
to Buttons
JMenuItems also have
JMenuItems also have
ActionListeners
ActionListeners
This is because they are
This is because they are
AbstractButtons
AbstractButtons
JComponent
JMenuBar AbstractButton
JCheckBoxMenuItem JRadioButtonMenuItem
JMenuItem
JMenu
JPopupMenu
JMenu Example JMenu Example
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar); // method of JFrame
JMenu testMenu = new JMenu("Test");
JMenuItem menuItem = new JMenuItem("Select Me");
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
menuSelected();
}
});
testMenu.add(menuItem);
menuBar.add(testMenu);
Text Handling Text Handling
Swing has text handling
Swing has text handling
capabilities similar to
capabilities similar to
AWT
AWT
JTextField,
JTextField,
JPasswordField,
JPasswordField,
JTextArea
JTextArea
However, it also has
However, it also has
sophisticated support for
sophisticated support for
viewing HTML and RTF
viewing HTML and RTF
JEditorPane
JEditorPane
JTextComponent
Document
<<interface>>
JTextField JTextArea JEditorPane
DocumentListener
<<interface>>
JList JList
JList is the primary Swing list class
JList is the primary Swing list class
Its like the AWT List widget except:
Its like the AWT List widget except:
The widget doesnt support adding &
The widget doesnt support adding &
removing elements directly
removing elements directly
Adds customized data models
Adds customized data models
Adds custom element rendering
Adds custom element rendering
Simple JList Example Simple JList Example
/*
* You must place a Jlist inside a JScrollPane to get scroll bars!
*/
public ExampleSimpleList ( ) {
String[] strings = {"Bob", "Carol", "Ted", "Alice", "Jane", "Fred", "Sue"};
JScrollPane scroller = new JScrollPane();
JList aList = new JList(strings);
scroller.getViewport().add(aList);
getContentPane().add(scroller);
}
JList Constructors JList Constructors
Jlist has four constructors
Jlist has four constructors
JList()
JList()
JList(Object[])
JList(Object[])
JList(Vector)
JList(Vector)
JList(ListModel)
JList(ListModel)
Use the array and Vector versions only
Use the array and Vector versions only
for simple, static lists
for simple, static lists
For more complex lists, use a ListModel
For more complex lists, use a ListModel
ListModel ListModel
A ListModel
A ListModel
represents a list of
represents a list of
elements to a JList
elements to a JList
Subclass
Subclass
AbstractListModel
AbstractListModel
to override getSize()
to override getSize()
and getElementAt()
and getElementAt()
contentsChanged( )
ListModel
getSize( )
getElementAt( )
addListDataListener( )
removeListDataListener( )
AbstractListModel
addListDataListener( )
removeListDataListener( )
ListDataListener
intervalAdded( )
intervalRemoved( )
<<interface>>
<<interface>>
fireContentsChanged( )
fireIntervalAdded( )
fireIntervalRemoved( )
ListModels ListModels
There would be several reasons you
There would be several reasons you
might make a ListModel
might make a ListModel
Loading database information as it is
Loading database information as it is
requested
requested
Synthetic lists of calculated items
Synthetic lists of calculated items
As our example well store information
As our example well store information
in a hashtable, and display the keys as
in a hashtable, and display the keys as
they were added to the hashtable
they were added to the hashtable
Example ListModel Example ListModel
public class CustomListModel extends AbstractListModel {
Hashtable data = new Hashtable();
Vector orderedKeys = new Vector();
public void put(Object key, Object value) {
data.put(key, value);
if (!orderedKeys.contains(key))
orderedKeys.addElement(key);
fireContentsChanged(this, -1, -1);
}
public Object get(Object key) { return data.get(key);}
public Object getElementAt(int index) { return orderedKeys.elementAt(index);}
public int getSize() { return orderedKeys.size();}
}
ListModel Example ListModel Example
public ExampleCustomListModelList ( ) {
JPanel outerPanel = new JPanel();
outerPanel.setLayout(new BorderLayout());
JScrollPane scroller = new JScrollPane();
JList aList = new JList(buildCustomListModel());
scroller.getViewport().add(aList);
JButton button = new JButton("Add");
button.addActionListener(this);
outerPanel.add(scroller, BorderLayout.NORTH);
outerPanel.add(button, BorderLayout.SOUTH);
getContentPane().add(outerPanel);
}
public void actionPerformed(ActionEvent e) {
model.put("As", "If");
}
JList Events JList Events
JLists support the ListSelection event
JLists support the ListSelection event
notification
notification
Clients implement the
Clients implement the
ListSelectionListener interface
ListSelectionListener interface
void valueChanged(ListSelectionEvent e)
void valueChanged(ListSelectionEvent e)
A ListSelectionEvent knows several
A ListSelectionEvent knows several
things
things
first selected index
first selected index
last selected index
last selected index
getValueIsAdjusting()
getValueIsAdjusting()
JList Event Example JList Event Example
public class ExampleListListening extends JFrame implements ListSelectionListener {

ExampleListListening() {

JList aList = new JList(someModel);


aList.addListSelectionListener(this);

public void valueChanged(ListSelectionEvent e) {


if (!event.getValueIsAdjusting()) {
String value = event.getSource().getSelectedValue();
System.out.println(Selection is + value);
}
}
}
List Cell Rendering List Cell Rendering
JList gives you the option to display not
JList gives you the option to display not
just Strings, but graphical icons as well
just Strings, but graphical icons as well
You need to create a new cell renderer
You need to create a new cell renderer
implement the ListCellRenderer interface
implement the ListCellRenderer interface
set the custom text and icon (image) in this
set the custom text and icon (image) in this
class
class
JTable JTable
JTable is a Tabular (row-column) view with
JTable is a Tabular (row-column) view with
read-only or editable cells
read-only or editable cells
Can create a JTable on:
Can create a JTable on:
Two Arrays
Two Arrays
2d array of data, 1d array of column headings
2d array of data, 1d array of column headings
Two Vectors
Two Vectors
(data of length row X columns), column
(data of length row X columns), column
headings headings
TableModel, (optionally) ListSelectionModel and
TableModel, (optionally) ListSelectionModel and
TableColumnModel
TableColumnModel
Table Models Table Models
TableModel is an
TableModel is an
interface that defines
interface that defines
the row/column
the row/column
behavior
behavior
AbstractTableModel
AbstractTableModel
implements most of the
implements most of the
behavior
behavior
you implement you implement
getColumnCount(),
getColumnCount(),
getRowCount(),
getRowCount(),
getValueAt()
getValueAt()
TableModel
getColumnCount( )
getRowCount( )
getValueAt( )
isCellEditable( )
AbstractTableModel
JDBCAdapter
YourTableModel
<<interface>>
Example Table Model Example Table Model
public ExampleTableCustomModel() {
super();
JTable table = new JTable(new CustomDataModel());
createColumnHeadings(table);
getContentPane().add(table.createScrollPaneForTable(table));
}
public void createColumnHeadings(JTable table) {
String headers[] = {"Zero", "One", "Two", "Three", "Four"};
table.setAutoCreateColumnsFromModel(false);
for (int i=0; i<5; i++) {
TableColumn column = new TableColumn(i);
column.setHeaderValue(headers[i]);
table.addColumn(column);
}
}
Example Custom Model Example Custom Model
public class CustomDataModel extends AbstractTableModel {
/**
* getColumnCount returns 0 since we will create columns ourselves
*/
public int getColumnCount() { return 0;}
public int getRowCount() {return 5;}
/**
* getValueAt is semi-bogus; it returns a string of row * column.
*/
public Object getValueAt(int row, int col) {
return Integer.toString(row * col);
}
}
Table Selection Table Selection
There are several selection attributes of
There are several selection attributes of
JTable you can set
JTable you can set
setRowSelectionAllowed(boolean value)
setRowSelectionAllowed(boolean value)
setColumnSelectionAllowed(boolean
setColumnSelectionAllowed(boolean
value)
value)
setSelectionForeground(Color value)
setSelectionForeground(Color value)
setSelectionBackground(Color value)
setSelectionBackground(Color value)
You can also turn horizontal and vertical
You can also turn horizontal and vertical
lines on and off
lines on and off
List Selection List Selection
JTables support ListSelection
JTables support ListSelection
notification
notification
Clients must implement the
Clients must implement the
ListSelectionListener interface
ListSelectionListener interface
Just like JLists in that respect
Just like JLists in that respect
The Event doesnt carry the necessary
The Event doesnt carry the necessary
selection information
selection information
You need to query the table for selection
You need to query the table for selection
information
information
Use getSelectedRow(),
Use getSelectedRow(),
getSelectedColumn(), getValueAt()
getSelectedColumn(), getValueAt()
TableSelectionListener
TableSelectionListener
Example Example
public class ExampleTableSelection extends JFrame implements ListSelectionListener {

ExampleTableSelection() {

JTable table = new JTable(someModel);


ListSelectionModel selectionModel = table.getSelectionModel();
selectionModel.addListSelectionListener(this);

}
public void valueChanged(ListSelectionEvent e) {
JTable table = (JTable) e.getSource();
DefaultTableModel model = (DefaultTableModel) table.getModel();
int row = table.getSelectedRow();
int column = table.getSelectedColumn();
String value = (String) model.getValueAt(row, column);
System.out.println(Selected value is + value);
}

}
Swing Trees Swing Trees
JTree is a hierarchical display component
JTree is a hierarchical display component
allows expansion, contraction, editing of
allows expansion, contraction, editing of
nodes
nodes
JTree displays a TreeModel
JTree displays a TreeModel
TreeModel is built from TreeNodes
TreeModel is built from TreeNodes
MutableTreeNodes hold arbitrary objects
MutableTreeNodes hold arbitrary objects
TreeModel Hierarchy TreeModel Hierarchy
TreeNode is an interface
TreeNode is an interface
that describes node
that describes node
behavior
behavior
MutableTreeNode is an
MutableTreeNode is an
interface that allows
interface that allows
addition/removal of
addition/removal of
children
children
DefaultMutableTreeNode
DefaultMutableTreeNode
implements
implements
MutableTreeNode
MutableTreeNode
TreeNode
getParent( )
children( )
getChildAt( )
isLeaf( )
MutableTreeNode
remove(MutableTreeNode )
insert(MutableTreeNode, int )
setParent( MutableTreeNode)
setUserObject(Object )
DefaultMutableTreeNode
getUserObject( )
add( MutableTreeNode)
<<interface>>
<<interface>>
TreeNode Example TreeNode Example
public DefaultMutableTreeNode buildTree() {
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Classes");
DefaultMutableTreeNode level1a = new DefaultMutableTreeNode("Java");
DefaultMutableTreeNode level1b = new DefaultMutableTreeNode("Smalltalk");
root.add(level1a);
root.add(level1b);
level1a.add(new DefaultMutableTreeNode("Introduction to Java"));
level1a.add(new DefaultMutableTreeNode("Advanced Java"));
level1a.add(new DefaultMutableTreeNode("Enterprise Java Programming"));
return root;
}
public ExampleSimpleTree() {
JScrollPane scroller = new JScrollPane();
JTree tree = new JTree(buildTree());
scroller.getViewport().add(tree);
getContentPane().add(scroller);
}
Tree Selection Tree Selection
JTrees support the TreeSelectionEvent
JTrees support the TreeSelectionEvent
notification
notification
Clients must implement the
Clients must implement the
TreeSelectionListener interface
TreeSelectionListener interface
void valueChanged(TreeSelectionEvent e)
void valueChanged(TreeSelectionEvent e)
Use the JTree method getSelectionPath()
Use the JTree method getSelectionPath()
to get a TreePath that gives the
to get a TreePath that gives the
selection(s)
selection(s)
Tree Expansion Tree Expansion
JTrees also support the
JTrees also support the
TreeExpansionEvent notification
TreeExpansionEvent notification
Clients implement TreeExpansionListener
Clients implement TreeExpansionListener
void treeExpanded(TreeExpansionEvent e)
void treeExpanded(TreeExpansionEvent e)
void treeCollapsed(TreeExpansionEvent e)
void treeCollapsed(TreeExpansionEvent e)
You can ask the TreeExpansionEvent to
You can ask the TreeExpansionEvent to
getPath() and return the affected path
getPath() and return the affected path
Summary Summary
Swing is a comprehensive expansion and
Swing is a comprehensive expansion and
replacement for AWT
replacement for AWT
You've seen some basic and advanced
You've seen some basic and advanced
concepts in Swing Programming
concepts in Swing Programming
More Information More Information
For more information, see the Swing For more information, see the Swing
tutorials on the Sun Java Developer's tutorials on the Sun Java Developer's
Connection website Connection website
(http://developer.java.sun.com)
(http://developer.java.sun.com)
requires registration (free)
requires registration (free)
Steven Gutz, "Up to Speed With Swing, Steven Gutz, "Up to Speed With Swing,
2nd Edition", Manning, 2000 2nd Edition", Manning, 2000

You might also like