To convert a standalone
application to an applet, the layout
manager must be set
to match in the two frames. The work
that is done in the constructor
can be
transferred to init( )
method. Any necessary
functionality of main( ) may be
transferred to start( ), stop( ) or paint( ). The main( ) method
can
be left in the
applet as main( ) is not called.
The
getDocumentBase( ) &
getCodeBase( ) Methods
Applet also defines two
useful methods that can reference
the location of the Java
applet code and the location of the
HTML
code that contains the tag for the Java
applet. They
are handy because you may not know exactly what
these
paths are. The getDocumentBase( )
method returns the
URL of the directory containing the HTML
document (which
is referencing an applet). The getCodeBase(
) method returns
the URL representing the directory where
the applet class
file resides.
Applet's getCodeBase and getDocumentBase( ) methods
URL
getCodeBase( )
//
returns the code base for the applet class file as a URL
URL getDocumentBase( )
//
returns the URL naming the directory of the document
// containing the applet the
applet is embedded.
Example
Image cat = getImage(
getDocumentBase( ), "Cat.jpg" );
getCodeBase & getDocumentBase( ) Code Sample
//<applet code="WhatDir.class" width=400 height=200></applet>
import
java.net.*;
import java.awt.*;
import
java.applet.*;
public
class WhatDir extends Applet{
String
s1,s2,s3,s4;
URL code,doc;
public void init(){
code=getCodeBase();
doc=getDocumentBase();
s1="Code
Base";
s2=code.toString();
s3="Document Base";
s4=doc.toString();
}
public void paint(Graphics g){
g.drawString(s1,40,20);
g.drawString("_______________________",40,22);
g.drawString(s2,40,40);
g.drawString(s3,40,80);
g.drawString("_______________________",40,82);
g.drawString(s4,40,100);
}
}
It
is interesting to note when you run this code using
source code with
the APPLET
tag commented out, that
the getDocumentBase( )
method points to the source
code file, recognizing it to be
the 'HTML' document
associated with the applet.
AppletContext
AppletContext
is an interface that is implemented by an
object that represents the
Java runtime environment that
the applet
runs in. To use any of AppletContext's many
useful methods, one needs to get a handle to the
AppletContext. The
following example shows the method
that is used to acquire a reference to the AppletContext
object
AppletContext context= getAppletContext( );
AppletContext
defines some interesting methods such
as the getApplet( ) method
which returns the name of
the applet in the
document and getApplets( ) which
returns
all the applets in the document.
//
getApplet( ), getApplets( )
AppletContext
also defines the
method showDocument( ),
either
taking a URL or a URL as a path to a file named as
a
String. The method launches an HTML page in the
browser which is
showing the applet. This could be
handy
to use with HTML frames where the applet would
reside
in one frame and launched HTML pages would show in
an adjacent
frame.
// showDocument( )
The
showStatus( ) method will show
in the status bar
at the button of the
browser. The code below shows
the showDocument( ) and showStatus( )
methods being
used. The showStatus( )
method is easy to demonstrate
in appletviewer
however, with modern browsers, the
status message is changing
all the times with browser
events the
showStatus( ) method may only show a
message for an instance. // showStatus( )
AppletContext Code Sample
import java.net.*;
//
<applet code="ShowD.class" width=400
height=100></applet>
public
class ShowD extends Applet{
public
void init(){
try{
URL url=new
URL("http://sentex.net/~pkomisar/FloweredReptile");
getAppletContext( ).showDocument(url);
}catch(MalformedURLException me){}
}
public
void paint( Graphics g){
g.setFont(new Font("Monospaced", Font.BOLD,
22));
g.drawString("OK,
It's Hello World", 50, 60 );
getAppletContext( ).showStatus( "Puts the message
in the browser status line" );
}
}
Getting Parameters from the HTML Document
Just as values passed into
main( ) in a standalone program
come in as String values, values
passed into an applet
from an HTML document also come in as String objects.
Steps have to be
taken to convert
the values to other
forms.
The following applet
example reads three parameters
from the HTML page and stores their
values in instance
variables. Three parameters are specified in the
Applet
tag. All the values are strings. Note quotes allow multiple
words with spaces An applet reading these values uses
the NAME
identifiers as parameters to the getParameter( )
method.
//
values are read with the getParameter( ) method
Going in, the case used to
describe the value stored by
the 'name'
attribute is not significant. The string value
returned by the method is in Java's case-sensitve world
and thus is case-sensitve.
// Going in, on the HTML side, is
not case-sensitive
// while the Java return values are case sensitive
The following example shows this where
the string in
'name' is 'artisto'. The getParameter( ) method is
able
to reference that name value in a case insensitive
fashion.
The value stored in the 'value' reference though,
now that it is inside the Java
program will be case
sensitive.
Example
// in the applet tag
<param name="artisto" value="Pablo Picasso">
// in the applet
String value = getParameter("ArTiStO");
//
parameter pasted into getParameter( ) is not
// case sensitve while the
String value returned is
The following code
sample shows a few techniques to
avoid creating a null pointer
exception from being thrown.
Member variables of the class are
explicitly set to default
values to insure they are not null. In
addition, 'try catch'
blocks are used to catch for Exception
class which will
capture potential occurrences
of exceptions such as
ArithmeticFormatException or NullPointerException.
Finally
logic tests are done to confirm that values are not
equal to
null. These safety features help insure the applet
doesn't fail in a client's browser.
Parameter retrieving code sample
import
java.awt.*;
import java.applet.*;
import java.applet.Applet;
import
java.net.*;
/*
<applet
code="Params.class" width =300
height=300>
<param
name="artisto" value="Pablo Picasso">
<param
name=title
value="Bather With Beach Ball">
<param
name=image value="Bather.jpg">
<param
name=imageNo
value="32">
</applet>
*/
public class Params
extends Applet {
String
testedValue;
Image
ii;
URL ui;
TextField report;
String _artist =
"artist name";
String _title = "name of painting";
String _image =
"image";
String
_imageNumber="0";
int number=0;
public
void init( ) {
setBackground(Color.darkGray);
String s=null;
setLayout(new BorderLayout());
report=new TextField("Report");
report.setBackground(Color.gray);
report.setForeground(Color.white);
add(report,BorderLayout.SOUTH);
testedValue = getParameter("ArTiStO");
//
shows that going in the values stored in NAME is not case-sensitive
if
(testedValue != null){
_artist = testedValue;
}
testedValue = getParameter("title");
if
(testedValue != null){
_title = testedValue;
}
testedValue = getParameter("image");
if
(testedValue != null){
_image = testedValue;
}
ii =getImage(getCodeBase(),_image);
testedValue = getParameter("imageNo");
if
(testedValue != null){
_imageNumber=testedValue;
}
try{
number
= Integer.parseInt(_imageNumber);
s="# "+ number +" " + _title +
" " + _artist;
report.setText(s);
}
catch(Exception e){
e.printStackTrace();
}
}
// end of init( )
public void
paint(Graphics g){
if(ii!=null)
// another null pointer avoidance
g.drawImage(ii,58,30, this);
}
}
// The
following Plug-in Information, as well as the following
material regarding additional JComponents is not on the exam.
The Java Plug-In
Early
on, power
politics were at play with Java support
in browsers. Disagreements between Sun
and
Microsoft,
as well as Netscape's sometimes tardy adoption of
newer
versions of Java for their browser led Sun to adopt a
strategy of providing newer JDK
runtime environments
in the form of 'plug-ins'. This enabled
support for Swing
and more
sophisticated applets built on JApplet.
Netscape
4.77 and Internet Explorer 5.x shipped with
support for old
versions of the JDK circa 1.7.x. They
can
run applets built using AWT. For older
browsers to
support Swing the JDK plug-in
has to be downloaded.
Around
IE 5.x,
Microsoft announced it was dropping
support for Netscape style
plug-ins. (Plug-ins were
popularized by
Netscape.) IE 5.5 was shipped without
support plug-ins. As well Explorer was
shipped without
Java support.
//
this was the bad old days. Sun and Microsoft have
// since 'buried the
hatchet' more or less!
Ever
astute, Sun has the Active-X style plug-in for Java
ready to go for Explorer. The plug-in approach is really a
better way to go as the user is not restrained by
implementation timetables of the browser providers.
Later,
AOL's Netscape 6.2 did ship with support for Swing
built in. On the other hand, the new open-source Mozilla
(as well as the browser spin off, 'Firefox') aimed to lighten
downloading and left it to the user
to download the Java
plug-in.
~2007
As 2006 ends,
Netscape is in version 7, IE has just entered
version 7 and Firefox 2 has been released. A majority of
connections are highspeed and downloaded Java support
as a plug-in is fast and trouble free.
Solutions
Allowing Redirects to Obtain the Java Plug-In
The
following paper at the Sun site offers solutions
to control what has
been happening with Applets in
conjunction with the HTML world.
'Using
OBJECT, EMBED & APPLET tags in Java Plug-In'
can be found at
the following URL,
We
have seen in this note that the Object tag is the
recommended
replacement for the Applet tag. A
limitation of the Applet
tag is that it does not allow a
redirect to take place that would
allow the browser to
interrupt rendering the page and 'run off' to
procure
the Java Plug-In.
Using Windows Explorer
Window's
Explorer is said to be compliant with the
W3C's HTML recommendation
to use the OBJECT tag.
(Though we found the 'off the rack' form of the OBJECT
tag didn't seem to work in IE, there are other formulations
involving adding other attributes with unique identifiers
that would have have allowed to Object tag to work.)
The Object tag allows deferring an Applet's
execution
until after the Plug-In is obtained. The way this
mechanism
works is that the OBJECT Tag's 'classid' and 'codebase'
attributes are used to redirect to the Sun site to do the
Plug-In download and PARAM tags are substituted to
supply the
class information needed to run the specific
Java applet.
Example of an
Original Applet Tag
//
from Using OBJECT, EMBED and APPLET tags in Java Plug-In, at the Sun
site.
<APPLET
code="XYZApp.class" codebase="html/"
align="baseline"
width="200"
height="200">
<PARAM name="model"
value="models/HyaluronicAcid.xyz">
No Java 2 SDK, Standard Edition v 1.4.2 support for
APPLET!!
</APPLET>
New Object Tag that
Allows Redirect to Get Plug In
<OBJECT
classid="clsid:CAFEEFAC-0014-0002-0000-ABCDEFFEDCBA"
width="200" height="200" align="baseline"
codebase="http://java.sun.com/products/plugin/autodl/jinstall-1_4_2-windows-i586.cab#Version=1,4,2,0">
<PARAM name="code" value="XYZApp.class">
<PARAM name="codebase" value="html/">
<PARAM name="type"
value="application/x-java-applet;jpi-version=1.4.2">
<PARAM name="model"
value="models/HyaluronicAcid.xyz">
<PARAM name="scriptable" value="true">
No Java 2 SDK, Standard Edition v 1.4.2 support for
APPLET!!
</OBJECT>
Using
Netscape Navigator
Netscape on the other hand, uses the EMBED tag to
obtain
plug-ins. The EMBED tag is a sophisticated version of the
Applet tag that still retains many of the same attributes. This
allows the EMBED tag to redirect to obtain the plug-in while
still retaining some of the 'looks' of the old APPLET tag.
EMBED Tag Version of the Original Applet
// from Sun site paper
<EMBED
type="application/x-java-applet;jpi-version=1.4.1"
width="200"
height="200"
align="baseline" code="XYZApp.class"
codebase="html/" model="models/HyaluronicAcid.xyz"
pluginspage="http://java.sun.com/j2se/1.4.1/download.html">
<NOEMBED>
No Java 2 SDK, Standard Edition v 1.4.1 support for
APPLET!!
</NOEMBED>
</EMBED>
Giant
Fudge Combo That Works in Both Browsers
A 'Fudge'
exists that will please 'geeks' everywhere. It is
based on the fact
that IE has a proprietary tag, COMMENT
that it recognizes but
Netscape ignores. Also, Netscape
is said to not recognize the OBJECT tag
so a solution exists
where the EMBED tag is nested inside IE COMMENT
tags
inside the OBJECT tag. This results in a tag that will prompt
for the latest series of Java Plug-In in both Browser
environments.
// To
make this work the value specified to 'classid' and 'codebase'
// may need
to be updated.
'Fudge' That Works
in Both IE and Netscape //
from Sun site paper
<OBJECT
classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
width="200" height="200" align="baseline"
codebase="http://java.sun.com/products/plugin/1.4/jinstall-14-win32.cab#Version=1,4,0,mn">
<PARAM NAME="code" VALUE="XYZApp.class">
<PARAM NAME="codebase" VALUE="html/">
<PARAM NAME="type"
VALUE="application/x-java-applet;jpi-version=1.4">
<PARAM NAME="model"
VALUE="models/HyaluronicAcid.xyz">
<PARAM NAME="scriptable" VALUE="true">
<COMMENT>
<EMBED
type="application/x-java-applet;jpi-version=1.4"
width="200"
height="200" align="baseline" code="XYZApp.class"
codebase="html/"
model="models/HyaluronicAcid.xyz"
pluginspage="http://java.sun.com/j2se/1.4/download.html">
<NOEMBED>
No Java 2 SDK, Standard Edition v 1.4 support for
APPLET!!
</NOEMBED>
</EMBED>
</COMMENT>
</OBJECT>
JTabbedPane
JTabbedPane is a component that allows several
panels
to be displayed one at a
time. Tabs are provided to allow
selection of
the pane the user wishes to see. This
class
supplies behaviour similar to what was
produced when
the AWT CardLayout
manager was used.
JTabbedPane defers complexity
to it's add methods and
keeps
it's constructors simple. It has only two
constructors,
one a no-arg constructor and
one allows specifying where
the tabs are placed,
top, bottom, left or right. The
default
location is top. These can be specified
using the
SwingConstants class.
The addTab methods are overloaded to take a String
to
label the tab and a
component to display, or a String, an
Icon and
a Component, or a String, Icon,
Component
and a tool tip.
JTabbedPane Code Sample // once again you need to supply your images
import javax.swing.*;
import java.awt.*;
class Tabber extends JFrame{
Tabber(){
ImageIcon ike1=new ImageIcon("Apples.jpg");
ImageIcon ike2=new ImageIcon("Cezanne.jpg");
JLabel pic1=new JLabel(ike1);
JLabel pic2=new JLabel(ike2);
JLabel cover=new JLabel(" Early 20th Century ");
JTabbedPane
tabpane=new JTabbedPane( SwingConstants.TOP );
tabpane.addTab("Folio",cover);
tabpane.addTab("Picasso", pic1);
tabpane.addTab("Cezanne", pic2);
getContentPane().add(tabpane);
setSize(400,400);
setVisible(true);
}
public
static void main(String[]args){
new
Tabber();
}
}
JSplitPane
JSplitPane manages
two child components that can be
splitted vertically
or horizontally, using the class constants
JSplitPane.HORIZONTAL_SPLIT or VERTICAL_SPLIT.
The dividing bar
can be dragged to change the relative
proportion of
the viewable area
each of the 'twins' occupy.
The dividers location can be set with the setDividerLocation( )
method.
This method
is overloaded to take either an int value
representing pixels. The overloaded version of the method
takes a double value between 0.0 and 1.0 representing
the relative proportion that the two child components
occupy. The documentation states this second version
works based on an earlier provided preset value. The
implication is that the second method may be used
dynamically change to change the divide point.
In the code below,
one way of getting the second version
of the function to work is shown.
The orientation of
the frames can be set when the
component
is constructed or
after using a setOrientation( )
method. The minimum size of a frame can
be specified
with
the setMinimumSize( ) method. There are a number
of other methods
available
to control
the details of this
component which are outlined in the JDK
documentation.
They are all
straight forward to use.
JSplitPane
Code Sample
JToolBar
JToolbar is a
floatable 'Menu Bar' container. It can
be
populated with
icons that symbolized different tools. It
can occupy space vertically
or horizontally.
Although
the component is floatable, this may lead to unpredictable
placement after
resizing so it has been recommended in
some sources to set the
floatability property
to false
using
the setFloatable( ) method.
Toolbar Code Sample
import
javax.swing.*;
import java.awt.*;
class
Tool extends JFrame{
public static void main(String[]args){
Tool tool=new Tool();
JToolBar toolbar = new JToolBar();
toolbar.setFloatable(false);
toolbar.add(new JButton("button 1"));
toolbar.add(new JButton("button 2"));
toolbar.add(new JButton("button 3"));
tool.getContentPane().add(toolbar,
BorderLayout.SOUTH);
tool.setSize(300,300);
tool.setVisible(true);
}
}
Complex components are made up of several classes.
JList
is simpler than JTable, and in fact is a sort of
one-dimensional version of
JTable. By looking at this
component in some depth you will be better prepared
to add
JTable to your 'toolkit'.
JList & DefaultListModel
JList represents an
ordered list of elements. JList supplies
a user with a
selection of one or more items. It can be
used traditionally using
a non-model
approach or more
efficiently using the underlying MVC architecture. The
constructors supply a simple approach to providing a
short list using an array or vector.
When this approach is taken a read-only version
of the
model is constructed.
This limits how you can manipulate
the model
that represents your data. The
following line
shows that you can read your data
but can't use a set
method
to alter it. The getSize( ) and getElement( )
methods can be used to query the model.
Example
String[] offices = {"Cairo", "Venice",
"Berlin", "Budapest"};
JList company = new JList(offices);
ListModel model = company.getModel( );
int size = model.getSize( );
for(int i=0;i<model.getSize( );i++)
System.out.println(model.getElementAt(i));
DefaultListModel
AbstractListModel is a implementation of the ListModel
interface. DefaultListModel
class is a subclass of the
AbstractListModel class and based
on a Vector as the
storage class. It
generates ListData events. If you look
at
DefaultListModel's
methods they include
the set of
methods you could call on a vector.
The default list
model provides methods to manipulate
the data while the JList itself has methods that
control
the view of the data. In the following
example the model
is not just
read only and a new value, London,
was added
using a set method.
Example
import javax.swing.*;This is still not the most efficient technique
as a copy of
the data was used to load and
create another copy into
memory. An abstract
list model extension can be built
around
a collection of data allowing the list to be
modeled
on a single data source.
When data comes from a big array or
vector, you may
take the next
step and implement the ListModel interface.
ListModel
defines the getSize( ) method
we saw earlier
and the getElementAt( ) method.
These two methods
provide the basic
functions of supplying the size of the
list and
providing access to any element in it.
The interface
also defines the listener methods
for events representing
changes to the
list.
The AbstractListModel is an abstract class that
is provided
to take care of some of
the event handling details for you.
It leaves
only the getSize( ) and getElementAt( ) methods
for the user to implement.
Following the
AbstractListModel
is implemented. The Swing
package defines a a new ActionListener for JList
called
ListSelectionListener. The AWT
List class used the
ItemListener of the AWT event
package. There is also a
listener that
responds to items being added and removed
to
the list that we might have implemented.
This is the
ListDataListener interface.
A major advantage
of the following code is that only one
data model is used and as such is more efficient in terms
of both performance and memory usage.
Code Sample
import javax.swing.event.*;
import javax.swing.*;
import java.awt.*;
class BranchModel extends
AbstractListModel{
String[] offices = {"Cairo", "Venice", "Berlin", "Budapest", "Paris"};
public int getSize( ){
return offices.length;
}
public Object getElementAt(int index){
return(offices[index]);
}
}
class Destination extends JFrame
implements ListSelectionListener{
JTextField destination;
JList company;
ListModel model;
Destination(){
model=new BranchModel( );
company = new JList(model);
company.addListSelectionListener(this);
getContentPane( ).add(company);
destination =new JTextField( );
getContentPane( ).add(destination,BorderLayout.SOUTH);
pack();
setVisible(true);
}
public void
valueChanged(ListSelectionEvent
e){
destination.setText(
(String)company.getSelectedValue()
);
}
public static void
main(String[]args){
new Destination();
}
}
JTable is a highly
complex visual component made up
of several cooperating
parts. The table is designed to
provide an efficientview
of data stored
in a data model.
Much of JTables functionality is delegated to support
classes.
JTable and related classes are made available
by importing the table
package.
Example
import javax.swing.table.*;
Table Support Classses
A JTable header is
represented by JTableHeader class
object. Columns
are
instances of TableColumn class.
Selection is controlled by
ListSelectionModel
objects.
Table data is represented by TableModel class objects.
TableCellEditor
class objects are responsible for the
appearance of table cells.
Finally
the
TableCellRenderer
class is used to paint unedited cells.
Components of JTable
JTable
Constructors
JTable
has many constructors including a no-arg constructor,
and a constructor
that takes the
number of rows and columns.
These objects use the DefaultTableModel
to
represent data.
Another constructor is more elaborate and allows
passing
in
an
Object array of arrays and an array storing column names.
A fourth
constructor
is built on a TableModel. A fifth allows
passing in
TableModel
and TableColumnModel, a sixth accepts
TableModel, TableColumnModel
and
ListSelectionModel. Finally
there is a constructor that takes a vector
storing
row data and
a vector holding column names. The constructors are listed
briefly in the following table.
Brief
Summary of JTable Constructors
JTable( ) | - a JTable initialized with
default data,
column and selection models. |
JTable(int numRows, int numColumns) |
- a JTable with numRows and numColumns
of empty cells using DefaultTableModel. |
JTable(Object[][] rowData, Object[] columnNames) |
- a JTable displaying two dimensional
array values, rowData, with column names, columnNames. |
JTable(TableModel dm) | - a JTable initialized with a data
model provided and a default column and selection model. |
JTable(TableModel dm, TableColumnModel cm) |
- a JTable initialized data and column
models provided and a default selection model. |
JTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm) |
- a JTable initialized with a data,
column and selection models provided. |
JTable is also
able to take a vector representing row data
and a
second vector
representing columns.
The following
example shows a simple approach
to using
JTable. You will notice the getTableHeader method was
used to get a
reference to
the table header. This object
was then added to the north region of
the frames
border
layout. If this was not done explicitly, the column headings
would not have
shown. The header has an interesting
property. The columns can be
dragged
and
dropped allowing
them to be reordered using the mouse.
The table
package
which is nested inside the javax.swing
package has to be imported to get
access to the
JTableHeader
class. When a JTable is added to a scrollpane the
viewport's
preferred size can be controlled using the ( excessively long)
setPreferredScrollableViewportSize(
)
method. Intercell
spacing can be changed using the setIntercellSpacing(
)
method.
The Table Grid Appearance
The color of the
grid can be obtained using getGridColor
and grid color
can be set
with the setGridColor( ) method.
The table grid can be made visible
or hidden using
the
setShowGrid( ) method which takes a boolean true or
false
value.
The
methods setShowHorizontalLines( ) and
setShowVerticalLines( ) each take a
boolean
value
and
can be selectively used to show either vertical or horizontal
table
grid lines.
These methods can be used in various
combinations to toggle the flags
controlling
the visibility of
the grid lines. The different aspects of JTable
discussed
so
far are
contained in the first JTable example.
JTable Code Sample 1
import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
class Table1 {
Table1( ){
JFrame frame=new JFrame(" JTable Example 1" );
Vector rows = new Vector(3);
Vector row1=new Vector(3);
Vector row2=new Vector(3);
Vector row3=new Vector(3);
row1.addElement("Bill Dexter");
row1.addElement("927-3393");
row1.addElement("bill@bronze.ca");
rows.addElement(row1);
row2.addElement("Betty Barber");
row2.addElement("828-1221");
row2.addElement("bbarber@silver.uk");
rows.addElement(row2);
row3.addElement("Chris Copper");
row3.addElement("424-5343");
row3.addElement("ccopper@gold.net");
rows.addElement(row3);
Vector columns= new Vector(3);
columns.addElement("Names");
columns.addElement("PhoneNo");
columns.addElement("E_mail");
JTable table=new JTable(rows,columns);
table.setGridColor(Color.pink);
table.setShowGrid(false);
table.setShowVerticalLines(false);
table.setShowHorizontalLines(true);
JTableHeader header=table.getTableHeader( );
frame.getContentPane( ).add(table, BorderLayout.CENTER);
frame.getContentPane( ).add(header, BorderLayout.NORTH);
frame.setSize(400,300);
// frame.pack( );
// pack( ) creates a frame just big enough to fit what's put in it.
frame.setVisible(true);
}
public static void
main(String[]args){
new Table1( );
}
}
JTable supports several selection modes. An
version
of ListSelectionModel
is used to control column and
row selection.
The default implementation supplied is
DefaultListSelectionModel. Thus the selection
modes
available for the rows of JList
are available for the
rows and columns of JTable.
These include single and
multiple
selection modes where the multiple selection
modes may be sequential or random.
// supports ListSelectionModel
What is selected can be controlled using the
methods,
setRowSelectionAllowed( ) &
setColumnSelectionAllowed( )
methods which are
set to booleans, true or false. The
method
setSelectionMode( ) sets the selection mode
for
both rows and columns. If a different
selection pattern
is needed for rows and columns,
the getColumnModel( )
method
will return the column model and it's selection
mode
can be set separately from the
row selection mode.
ListSelectionModel selection
mode constants are listed
in the
following table.
ListSelectionModel Selection Mode
Constants
MULTIPLE_INTERVAL_SELECTION | - selects one or more sequential indice ranges |
SINGLE_INTERVAL_SELECTION | - select one contiguous range of indices at a time. |
SINGLE_SELECTION | - selects one list index at a time. |
The cell background
and foreground colors can be set with
the setSelectionBackground(
)
and setSelectionForeground( )
methods. The following lines can be added
to the previous
example.
Example
table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
table.setSelectionBackground(new Color(255,250,240));
table.setSelectionForeground(Color.blue);
Selection
Methods of JTable
Of JTable's many
methods, some are designed to effect
the selection
process.
setRowSelectionInterval(
) - Specifying two
integers to the
setRowSelectionInterval( )
method defines a range (which
includes the rows
specified by the two ints) that limit
the
number of rows that can be selected.
addRowSelectionInterval(
) - The
addRowSelectionInterval(
)
can be used to
increase the range selectable. There is a
similar
pair of methods for column selection.
clearSelection( ) - This method clears the collection set.
getSelectedRowCount(
) - returns
the number of rows that
are selected.
JTable uses a TableModel to represent data. The
table
model defines the key
methods used to access and set
data to the model
as well as to get the number
of rows
and columns. The model defines the
getRowCount(
)
and getColumn( )
count methods and the getValueAt( )
and
setValueAt(
) methods. The model
also defines the
addTableModelListener( ) and
removeTableModelListener( )
to register TableModelListeners for
TableModelEvent
objects.
The TableModel Event Class
The TableModelEvent class defines among other
constants
the INSERT
UPDATE and DELETE constants. This allow
determining
if the table change
represents one of these types
of events. The
TableModelEvent class has five
constructors
and the methods, getFirstRow( ),
getLastRow( ), getColumn( )
and getType( ).
// model
accomodates SQL
The TableColumnModel Interface
JTable columns have their own TableColumnModel
which
defines the addColumn( ),
removeColumn( ), moveColumn( )
and
setColumnMargin(
) methods for modifying
the model.
For querying the model there is the
getColumnCount( ),
getColumnIndex( ),
getColumn( ), setColumnSelectionAllowed( ),
getColumnSelectionAllowed(
),
getSelectedColumns( ),
getSelectedColumnCount(
),setSelectionModel( ) and
getSelectionModel( ).
For registering listeners
the interface includes the
addColumnModelListener( ) and
removeColumnModelListener(
)
methods.
The TableColumnModelEvent class
The TableColumnModel generates it's own event
object
type which has a single
constructor and the getFromIndex( )
and the
getToIndex(
) methods. This event
object is
generated when the column is added
or removed or moved.
The AbstractTableModel class is an abstract
implementation
of the TableModel
interface. Though the class is abstract
supplies
concrete definitions for most of
the methods of
TableModel. One approach to
building
a JTable is to extend
the
AbstractTableModel and supply the JTable
constructor
an object of the model
subclass. In extending AbstractTableModel
only
the following three methods
need to be provided.
AbstractTableModel Methods that must be overidden.
public int getRowCount( );
public int getColumnCount( );
public Object getValueAt(int row, int
column);
This abstract class provides default implementations
for most
of the methods in the
TableModel interface. It takes care of
the
management
of listeners and provides
some conveniences
for generating TableModelEvents
and dispatching them to the
listeners.
If the table is going to have column headers,
the methods
related to column
names must also be overidden.
AbstractTableModel Code Sample
import javax.swing.event.*;
import javax.swing.*;
import java.awt.*;
import
javax.swing.table.*;
class AbTab2 extends JFrame implements
ListSelectionListener{
ListSelectionModel selectModel;
AbTab2( ){
CourseModel model = new CourseModel();
JTable table=new JTable(model);
/* get selection model using getSelectionModel( ) register
'this' as the listener with the listselection model */
selectModel=table. getSelectionModel( );
selectModel.addListSelectionListener(this);
JTableHeader header= table.getTableHeader( );
getContentPane().add(header,BorderLayout.NORTH);
getContentPane().add(table);
setSize(500,300);
setVisible(true);
}
public static void
main(String[]args){
new AbTab2( );
}
public void
valueChanged(ListSelectionEvent
e){
int
min=selectModel.getMinSelectionIndex(
);
int max =
selectModel.getMaxSelectionIndex(
);
System.out.println
( "Min index
selected:
" + min + " Max index selected " + max );
/* pass these index values to
the AbstractTableModel getValueAt( ) method
These
values
then can be set to another component such as a
list
*/
}
}
class CourseModel extends
AbstractTableModel{
String[] colNames;
Object[][] data;
CourseModel( ){
super( );
colNames=new
String[]{"Course_Number",
"Course_Name",
"Description",
"Credits"
};
data=new Object[][]{
{"100", "Java","Intro","1
credit"},
{"200", "Java","Foundation
Classes","1 credit"},
{"300",
"Java","Advanced","1
credit"},
{"400", "HTML","General",
"1/2 credit"},
{"500", "SQL","General",
"1/2 credit"},
{"600",
"JavaScript","General","1
credit"},
{"700", "C &
C++","General","1
credit"},
{"800", "XML", "General",
"1 credit"},
{"900",
"Networking","Intro","1
credit"},
{"1000","Linux","Intro","1
credit"}
};
}
public int getRowCount( ){
return data.length;
}
public int getColumnCount( ){
return data[0].length;
}
public Object
getValueAt(int
row, int column){
return data[row][column];
}
// The column model related stuff
public String getColumnName(int
column){
return colNames[column];
}
public Class getColumnClass(int
column){
return
(data[0][column].getClass());
}
}
DefaultTableModel
When JTable is used
in simpler forms, the extension of
AbstractTableModel, DefaultTableModel, may be used.
Loading a JTable using a
DefaultTableModel
import
javax.swing.*;
// JTable & JFrame
import javax.swing.table.*; //
DefaultTableModel
import javax.swing.event.*; //
events
import java.awt.*; //
layouts
import
java.util.*;
// vectors
class
Tabler extends JFrame{
Tabler(){
Object[]
columnsArray=
{ "First_Name","Last_Name","Phone_Number"};
Object [][] dataArray={
{"Bob","Dennis","519 613 2224"},
{"John", "Doe","465 222 1234"},
{"Mike", "Xerox","987 234 9878"}
};
DefaultTableModel model=new
DefaultTableModel(dataArray,columnsArray);
model.setRowCount(7);
JTable
table=new
JTable(model);
JScrollPane
scrolledtable=new JScrollPane(table);
getContentPane().add(scrolledtable,BorderLayout.CENTER);
getContentPane().add
(new
JLabel("JTable
Example"),BorderLayout.NORTH);
setSize(500,400);
setVisible(true);
}
public static void main(String[] s){
new Tabler();
}
}
JTable
is a powerful visual component that has obvious
applications for providing an interface to data stored in
relational databases.
JTree
Another
major component which we do not have time to
look at is
JTree. It provides a component representation
of a tree data
structure. We leave it to you to look into this
component.