You are on page 1of 63

S dng JTable ca Swing trong

java
Nu chng ta hn s thy rng rt nhiu ng dng cn hin th d liu di dng bng biu. Trong
java, Swing cung cp cho chng ta mt lp thc hin iu ny l lp JTable.
Bn cnh kh nng hin th thng tin, JTable cng cho php chng ta d dng sa i thng tin, t kch
c v u cho tng ct, v iu khin cch d liu hin th trong bng biu. u tin chng ta hy hc
cch hin th thng tin ln bng biu v y l chc nng c bn v cng cn thit nht. Bn cht ca
JTable l n ly d liu t mt data model v hin th d liu t ln. V th, trc tin chng ta s
nghin cu v ci data model.
Data model
Ngoi lp JTable, Swing cn cung cp mt s cc lp, cc interface khc na. Cc lp, interface ny s
c s dng bi lp JTable v chng c nh ngha trong gi javax.swing.table. Mt trong s l
interface TableModel. Interface TableModel to nn mt s giao tip gia mt ci JTable v ci data
model ca n. Ging nh cc thnh phn khc ca Swing, JTable c thit k theo m hnh
model/view/controller m cc thnh phn dng hin th (JTable )s c tch ring bit so vi
cc thnh phn lu tr d liu (TableModel). iu ny mang n mt s linh ng hn trong thit k v
tng kh nng s dng li cc thnh phn. Tuy nhin, n cng lm cho vic s dng JTable tr nn
phc tp hn. Nhng cng tht may mn, Swing cng cung cp mt s ci t mc nh lm cho vic s
JTable tr nn phc tp hn trc.
Nh ni, TableModel c nhim v l cung cp d liu hin th cho JTable. Bn cnh , n cng c
nhim v cung cp cho JTable mt vi thng tin khc nh:
S lng dng v s lng ct trong bng
Kiu d liu trong tng ct
Tiu cho tng ct
C cho php sa gi tr trong mt hay khng
Interface TableModel bao gm 9 phng thc cn c ci t ging nh di y.

Cn phi ci t c 9 phng thc thc s khng thch hp trong nhng trng hp chng ta mun to
nhanh mt bng. Nhng java cng cung cp cho chng ta cc lp khc nh
lAbstractTableModel v DefaultTableModel. C hai lp ny u ci t phn no cc phng thc
ca interface TableModel. V th, khi s dng th chng ta s tn t cng hn. Chng hn nh nu chng
ta k tha lp AbstractTableModel th chng ta chi cn ci t 3 phng thc sau:
Phng thc tr v s dng ca bng
Phng thc tr v s ct ca bng
Phng thc tr v gi tr ca mi
Di y, chng ta to mt lp l TableValues trong file TableValues.java. Lp ny k tha lp
AbstractTableModel v s l data model cho mt ci JTable.

public class TableValues extends AbstractTableModel{

public final static boolean GENDER_MALE = true;
public final static boolean GENDER_FEMALE = false;

public Object[][] values = {
{
"Clay", "Ashworth",
new GregorianCalendar(1962, Calendar.FEBRUARY, 20).getTime(),
new Float(12345.67), new Boolean(GENDER_MALE)
}, {
"Jacob", "Ashworth",
new GregorianCalendar(1987, Calendar.JANUARY, 6).getTime(),
new Float(23456.78), new Boolean(GENDER_MALE)
}, {
"Jordan", "Ashworth",
new GregorianCalendar(1989, Calendar.AUGUST, 31).getTime(),
new Float(34567.89), new Boolean(GENDER_FEMALE)
}, {
"Evelyn", "Kirk",
new GregorianCalendar(1945, Calendar.JANUARY, 16).getTime(),
new Float(-456.70), new Boolean(GENDER_FEMALE)
}, {
"Belle", "Spyres",
new GregorianCalendar(1907, Calendar.AUGUST, 2).getTime(),
new Float(567.00), new Boolean(GENDER_FEMALE)
}
};

public int getRowCount() {
return values.length;
}

public int getColumnCount() {
return values[0].length;
}

public Object getValueAt(int rowIndex, int columnIndex) {
return values[rowIndex][columnIndex];
}

}

y, d liu chnh l mng hai chiu values. V cho v d n gin nn chng ta vit d liu trong
code (hard-code). Tuy nhin, ngoi thc t, d liu ca chng ta thng s ly ra t c s d liu.
Nh ni trn, v kt tha lp AbstractTableModel, nn chng ta phi ci t 3 phng thc
l getRowCount(), getCollumnCount() v getValueAt()
By gi chng ta to mt lp SimpleTableTest to mt JTable v gn cho n ci model va to trn
on code trong file SimpleTableTest.java s nh sau:

public class SimpleTableTest extends JFrame{
protected JTable table;

public SimpleTableTest(){
Container pane = getContentPane();
pane.setLayout(new BorderLayout());
TableValues tv = new TableValues();
table = new JTable(tv);
pane.add(table, BorderLayout.CENTER);
}

public static void main(String [] args){
SimpleTableTest stt = new SimpleTableTest();
stt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
stt.setSize(400, 200);
stt.setVisible(true);
}
}

Trong contructor ca lp SimpleTableTest ta c hai dng lnh sau:

TableValues tv = new TableValues();
table = new JTable(tv);
Dng lnh th nht l to ra mt ci data model tn l tv. Dng lnh th hai to ra mt ci JTable c tn
l table v gn cho n ci model tv. Sau khi chy chng trnh, d liu trong model tv s c hin th
ln ci bng table nh sau:

Nh vy, chng ta cng thy c, vic s dng AbstractTableModel c v nh nhnh hn rt nhiu so
vi vic s dng TableModel. Bn cnh , vic s dng DefaultTableModel cn d dng hn nhiu so
vi vic s dng AbstractTableModel tuy nhin n li khng c khuyn khch s dng. Nguyn
nhn l bi v bn thn DefaultTableModel t ng to ra cc tham chiu n cc d liu thay v chng
ta phi ci t mt phng thc no ging nh getValueAt() khi s dng AbstracTableModel. iu
ny dn ti mt s khng mm do v khng th m rng trong qu trnh s dng. Bn cnh , mt
vn khc gp phi chnh l vn sa d liu cc . hiu ti sao DefaultTableModel khng c
kh nng m rng, chng ta cn phi hiu ci JTable n lm vic nh th no.
Nh chng ta bit, TableModel c nhim v ch ra trong bng c bao nhiu dng v c bao nhiu ct.
Hai phng thc getRowCount() v getColumnCount() s c gi ngay khi mt bng c to v hin
th. Tuy nhin, mt bng s khng bao gi tham chiu n ton b d liu trong TableModel m ch tham
chiu n mt phn no hin th. Cho v d nh sau, gi s chng ta to mt data model tr
v gi tr l 100 t phng thc getRowCount(), nhng ci bng ca chng ta th nm trong mt ci ca
s cun m mi ln chng ta ch nhn ti a c 10 dng. Khi bng c hin th, u tin n s truy
cp n 10 dng u ca d liu trong TableModel, v s truy cp n d liu cho cc dng khc ch khi
chng ta cun thanh cun xung. Ti sao iu ny li quan trng nh vy? Bi v nh th n cho php
chng ta hin th mt lng ln d liu vo trong JTable m khng cn ti ton b d liu vo b nh
mt cch ng thi. Lc ny, TableModel ch cn ti d liu theo nhu cu, v gim thiu ti a dung
lng b nh c s dng.
Vi iu ny, gi chng ta quay li vic s dng DefaultTableModel v vic n t to ra cc tham chiu
n d liu bn trong n. Bi v n yu cu tham chiu ti ton b d liu, nn ton b d liu phi nm
bn trong b nh chng no chng ta vn cn s dng ci model . y chnh l nhc im ca
vic s dng DefaultTableModel v mt li khuyn l chng ta nn dng AbstractTableModel thay
th. Tuy nhin, vi mt lng d liu nh, chng ta vn c th cn nhc s dng DefaultTableModel bi
v n n gin. Hn na d liu c cache sn vo trong b nh s gip chng ta truy cp nhanh hn.
Tr li vi v d trn, chng ta thy rng c mt vn l khi ca s ca chng ta thay i sao cho
kch thc ca n nh hn kch thc ca bng th c mt phn d liu s b mt khng th nhn thy
nh hnh di y:

Thm vo na, cc ct ca chng ta cha c tiu . Tt c nhng vn ny s c gii quyt trong
phn 2.
Trong phn 1 chng ta bit cch a d liu t mt TableModel ln mt JTable. Trong phn ny
chng ta s tip tc tm hiu v cch s dng JTable ca Swing trong java nh l to ca s cun cho
bng, to tiu cho cc ct trong bng v thao tc vi hng v ct.
To ca s cun cho bng
Trong bt c trng hp no m chng ta c mt s lng ln thng tin cn hin th, chng ta s
cn n lp JScrollPane. Lp ny to ra mt ca s cun cho php chng ta nhn mt lng ln thng
tin ch bng thao tc ko thanh cun trn ca s. Tr li v d ln trc chng ta ch cn thay i vi
dng trong lp SimpleTableTest trong file SimpleTableTest.java. Trong on code di y, nhng dng
in m mu xanh l nhng dng thm mi vo on code c.

public class SimpleTableTest extends JFrame{
protected JTable table;

public SimpleTableTest(){
[...]
table = new JTable(tv);
JScrollPane jsp = new JScrollPane(table);
pane.add(jsp, BorderLayout.CENTER);
}

public static void main(String [] args){
[...]
}
}
By gi chy chng trnh chng ta s thy mt thanh cun xut hin khi m kch thc ca s nh hn
kch thc ca bng nh hnh di y

Nu chng ta cng thy vic to mt ca s cun cho bng cng s lm xut hin tiu cho cc
ct. Theo mc nh, tiu cc ct s ln lt c nh theo th t bng ch ci bt u t A ri n
B, C Vy lm sao cho tiu ca cc ct ng vi nhng tn m chng ta mong mun. Phn di
y s hng dn to tiu cho cc ct.
To tiu cho cc ct trong bng
Trc tin phi nh to ra mt ca s cun cho bng . Nu nh khng to ca s cun cho bng th
tiu cc ct cng khng th xut hin. Sau , chng ta c th t tn cho tiu ca cc ct trong
bng bng cch ci t phng thc getColumnName() trong TableModel ca chng ta. Trong v d,
chng ta ch vic sa lp TableValues bng cch thm vo cc on m mu xanh sau:

public class TableValues extends AbstractTableModel{

public final static boolean GENDER_MALE = true;
public final static boolean GENDER_FEMALE = false;
public final static String[] columnNames = {
"First Name", "Last Name", "Date of Birth", "Account Balance","Gender"
};

public Object[][] values = {
[...]
};

public int getRowCount() {
return values.length;
}

public int getColumnCount() {
return values[0].length;
}

public Object getValueAt(int rowIndex, int columnIndex) {
return values[rowIndex][columnIndex];
}

@Override
public String getColumnName(int column){
return columnNames[column];
}
}

Gi chy chng trnh, cc tiu cc ct c tn rt ng hong

Chng ta rng khi m kch thc ca s nh hn kch thc ca bng. Mt thanh cun dc s xut
hin nhng li khng c mt thanh cun ngang. Thay vo , cc ct trong bng s t ng co li ging
nh hnh di y.

hiu ti sao iu ny li xy ra, chng ta cn phi tm hiu v thit k ca JTable v cc lp h tr
ca n lm vic nh th no.
Thit k hng ct (column-oriented design) ca JTable
Thnh phn JTable c thit k hng ct, mi mt JTable s c mt tham chiu n mt ci t ca
interface TableColumnModel. Mt ci t ca TableColumnModel chng hn
nhDefaultTableColumnModel nm trong gi javax.swing.table v miu t mt tp hp cc ct trong
mt ci JTable. Mi mt ct c biu din l mt i tng ca lp TableColumn. Cho v d nh sau,
gi s chng ta to mt TableModel trong s ct ca bng c ch nh l 5. Nu sau chng ta
to mt i tng ca lp JTable v i tng ny s dng ci model va to th lc mt i tng
ca lp DefaultTableColumnModel s c to ra. i tng ca lp JTable s ly thng tin v s ct
ca bng t TableModel, sau to ra 5 i tng ca lp TableColumn ri thm 5 i tng ny vo
i tng ca lp DefaultTableColumnModel va to trc .
Mi i tng ca lp TableColumn mang thng tin cho mt ct nh tiu ca ct , gi tr v rng
hin ti, rng nh nht, rng ln nht, rng c a thch ca ct , ch nh xem ct c
c php thay i kch thc hay khng. Ban u, khi m c to, rng hin ti v rng a
thch ca mt ct c t gi tr l 75, rng nh nht l 15 v rng ln nht c t n v hn
(Integer.MAX_VALUE).
Sau khi chng ta to mt ct, chng ta c th thay i gi tr rng ca ct mt cch trc tip bng vic
s dng cc phng thc nh setWith, setMaxWith, setMinWidth, setPreferedWidth.
Mi mt i tng ca lp JTable u c thit lp mt ch ch ra cch n x l khi m kch
thc ca n b thay i. Ch ny c th ri vo mt trong 5 gi tr. Mi gi tr tng ng vi mt
hng s c nh ngha trong JTable nh sau:
AUTO_RESIZE_ALL_COLUMNS
AUTO_RESIZE_LAST_COLUMN
AUTO_RESIZE_NEXT_COLUMN
AUTO_RESIZE_OFF
AUTO_RESIZE_SUBSEQUENT_COLUMNS
Nhng gi tr ny quy nh cch cc ct ca bng thay i kch thc khi m rng ca bng hoc mt
trong bng thay i gi tr.
S thay i kch thc ca bng
Nu ch t ng thay i kch thc ca bng c t gi tr l AUTO_RESIZE_OFF th vic thay
i kch thc ca bng khng lm nh hng n kch thc hin ti ca cc ct trong bng . Nhng
nu n nhn mt trong bn gi tr cn li th mt s thay i v kch thc ca bng s c phn phi
u n tt c cc ct trong bng theo t l da trn kch thc a thch (prefered width) ca cc ct.
Cho v d, gi s rng mt bng c hai ct trong mt ct c rng a thch l 200 v ct cn li c
rng a thch l 100. Trong trng hp ny, ct th nht s chim hai phn ba chiu rng ca bng,
v ct th hai chim mt phn ba rng cn li. Nu bng c ko rng ra thm 30 pixel th ct
th nht s rng ra thm 20 pixels v ct th hai rng ra thm 10 pixel.
Nu ch t ng thay i kch thc ca bng c t gi tr l AUTO_RESIZE_OFF, v tng
rng ca tt c cc ct ln hn rng ca bng th khi thanh cun ngang s xut hin. By gi quay
tr li v d, ta thay i contructor ca lp SimpleTableTest nh sau:

public class SimpleTableTest extends JFrame{
protected JTable table;

public SimpleTableTest(){
[...]
table = new JTable(tv);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JScrollPane jsp = new JScrollPane(table);
pane.add(jsp, BorderLayout.CENTER);
}

public static void main(String [] args){
[...]
}
}

Mi ct c mt rng mc nh l 75, khi rng ca bng qu nh hin th tt c cc ct, mt
thanh trt ngang xut hin nh hnh di y:

S thay i kch thc ca ct
Chng ta c thy vic thay i rng ca mt bng nh hng nh th no n rng ca cc
ct bn trong bng . Chng ta cn phi xem xt n vic thay i kch thc ca mt ct s nh
hng n kch thc ca cc ct khc nh th no. Chng ta c th thay i kch thc ca ct bng
vic gi cc phng thc trong code hoc c th thay i qua giao din ca JTable.
Khi kch thc ca mt ct thay i, n s nh hng n kch thc ca cc ct khc ty thuc vo
vic ch t ng thay i kch thc ca bng c t gi tr nh th no. Trong phn ny, chng ta
s xem xt s thay i trn mi gi tr c th.
AUTO_RESIZE_OFF
ch ny khi mt ct thay i kch thc s khng lm nh hng n kch thc ca cc ct khc
trong bng. Nu kch thc ca bng nh hn tng kch thc ca tt c cc ct, thanh trt nm ngang
s xut hin. Nu kch thc ca bng ln hn tng kch thc ca tt c cc ct, s c nhng khong
trng trong bng nh hnh di y

AUTO_RESIZE_NEXT_COLUMN
Trong ch ny, khi mt ct thay i kch thc th ct bn phi lin st n s c ni rng hoc b co
li. Trong hnh di y, ct Date of Birth tng kch thc, ct pha bn phi lin st n l ct Account
Balance s b co li

AUTO_RESIZE_SUBSEQUENT_COLUMNS
Trng hp ny gn ging nh trng hp s dng AUTO_RESIZE_NEXT_COLUMN, ngoi tr rng
khi mt ct thay i kch thc th tt c cc ct pha bn phi n s c m rng hay co li. Trong
hnh di y, ct Date of Birth m rng ra khin hai ct pha bn phi n l Account Balance v Gender
b co li

chnh lch gia kch thc ban u v kch thc v sau ca ct c kch thc b thay i (trong v
d l ct Date of Birth) gi l gi tr delta. Gi tr ny c phn phi theo t l n cc ct pha bn phi
ct .
AUTO_RESIZE_LAST_COLUMN
Trong ch ny, gi tr delta c phn phi n ct cui cng ca bng v c th lm cho rng ca
n ln hn hoc nh i. Trong hnh di y, khi kch thc ca ct Date of Birth tng ln l nguyn
nhn ct Gender b co li

AUTO_RESIZE_ALL_COLUMNS
y chnh l ch mc nh cho mt JTable nu chng ta khng ch nh ch t ng thay i kch
thc cho n. Trong ch ny, nu ta thay i kch thc cho mt ct, tt c cc ct khc trong bng
cng s thay i kch thc theo t l. Trong hnh di y, ct Date of Birth tng kch thc lm cho tt
c cc ct khc nh i.

n y, c mt vn l nh dng d liu trong cc ct cha c theo mun. V d, gi tr d liu
ct gii tnh hin th l true v false trong khi nh ra phi l Male v Female mi chun. Hoc nh
ct ti khon hin th cc gi tr kiu s nhng li khng theo chun nh dng ca tin t.
Tt c nhng vn ny s c gii quyt trong phn 3.

Nh ni phn 2, v d, d liu trong cc ct ca bng khng hin th ng nh nhng g m chng
ta mong mun. C th l ba ct sau
Ct Date of Birth hin th c ngy v gi trong khi chng ta mun n ch hin th ngy thi v nh dng
ca ngy sinh s khng c th.
Ct Account Balance ch hin th kiu s n gin trong khi chng ta mun hin th d liu ct ny di
nh dng ca tin t.
Ct Gender hin th gii tnh th phi hin th gi tr l Male hoc Female thay v true or false
nh dng biu din d liu cho mt trong bng
Mi mt trong bng JTable c v nn bi mt i tng gi l cell renderer. i tng ny sinh ra t
cc lp c ci t interface l TableCellRenderer. Trong interface ny c nh ngha mt phng thc
l getTableCellRendererComponent(). Phng thc ny tr v mt tham chiu n mt thnh phn v
thnh phn ny s thc hin chc nng v nn hnh hi cho ci ca bng. Mt cch tin li nht cho
chng ta l nh ngha ra mt lp va ci t interface TableCellRenderer v cng va k tha t cc
lp c kh nng thc hin chc nng v (JComboBox, JTextBox). Chnh v vy nn thng thng
mt i tng ca lp ci t interface TableCellRenderer, trong phng thc
getTableCellRendererComponent() ca n s tr v mt tham chiu n chnh n. Phng thc
getTableCellRendererComponent() gm c cc tham s u vo sau:
Mt tham chiu n ci JTable c cc d liu ang c v
Mt tham chiu n gi tr ca d liu
Mt bin c xc nh xem ny c ang c chn (kch chut vo) hay khng
Mt bin c xc nh xem ny c l mt nhp d liu u vo v ang c tr n hay khng
Mt ch s hng ca ang c v
Mt ch s ct ca ang c v
Ngoi vic tr v mt tham chiu n mt thnh phn c kh nng hin th, phng thc
getTableCellRendererComponent() cn c nhim v khi to trang thi ban u cho thnh phn . Ch
rng mt trong nhng tham s u vo ca phng thc l mt tham chiu n gi tr ca mt . V
gi tr ny s c lu trong ci thnh phn trc khi phng thc tr v mt tham chiu n n.
JTable cung cp sn mt s cc renderers c nh ngha trc, tuy nhin trc ht chng ta hy
tm hiu cch to mt renderer ty bin.
To renderer ty bin
Tr li v d, chng ta s to mt renderer ty bin cho ct Gender, sao cho mi ca n hin th di
dng mt JComboBox v gi tr true v false s ln lt c thay th bng Male v Female.
Trc ht ta sa ci model TableValues trong file TableValues.java bng cch thm vo cc hng s, cc
hng s ny ln lt lu cc ch s ca cc ct trong bng. Ct u tin s c ch s l 0 v c th tng
ln mt n v cho cc ct tip sau

public class TableValues extends AbstractTableModel{

public final static int FIRST_NAME = 0;
public final static int LAST_NAME = 1;
public final static int DATE_OF_BIRTH = 2;
public final static int ACCOUNT_BALANCE = 3;
public final static int GENDER = 4;

public final static boolean GENDER_MALE = true;
public final static boolean GENDER_FEMALE = false;

public final static String[] columnNames = {
"First Name", "Last Name", "Date of Birth", "Account Balance","Gender"
};

public Object[][] values = {
[...]
};

public int getRowCount() {
return values.length;
}

public int getColumnCount() {
return values[0].length;
}

public Object getValueAt(int rowIndex, int columnIndex) {
return values[rowIndex][columnIndex];
}

@Override
public String getColumnName(int column){
return columnNames[column];
}
}

Sau to mt renderer c tn l GenderRenderer, lp ny nm file GenderRenderer.java nh sau:

public class GenderRenderer extends JComboBox implements TableCellRenderer{

public GenderRenderer(){
super();
addItem("Male");
addItem("Female");
}

public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
if(isSelected){
setForeground(table.getSelectionForeground());
super.setBackground(table.getSelectionBackground());
}else{
setForeground(table.getForeground());
setBackground(table.getBackground());
}

boolean isMale = ((Boolean) value).booleanValue();
setSelectedIndex(isMale?0:1);

return this;
}
}

Nh ni trn, ci renderer ny s ci t interface TableCellRenderer v cho thut tin n k
tha lun mt thnh phn c kh nng hin th chnh l JComboBox. V vy, trong phng thc
getTableCellRendererComponent() c tr v tham chiu n chnh ci renderer bng dng lnh return
this.
Tip theo, trong lp SimpleTableTest file SimpleTableTest.java, ta thay i nh sau:

public class SimpleTableTest extends JFrame{
protected JTable table;

public SimpleTableTest(){
[...]
table = new JTable(tv);
TableColumnModel tcm = table.getColumnModel();
TableColumn tc = tcm.getColumn(TableValues.GENDER);
tc.setCellRenderer(new GenderRenderer());
JScrollPane jsp = new JScrollPane(table);
pane.add(jsp, BorderLayout.CENTER);
}

public static void main(String [] args){
[...]
}
}

Sau khi chy chng trnh chng ta s thy mi trong ct Gender s c biu din bi mt
JComboBox vi gi tr l Male hoc Female nh hnh di y:

Mt iu quan trng m chng ta phi bit l cch m mt renderer c thm vo mt i tng ca
JTable s khng ging vi cch mt thnh phn c th hin th c thm vo mt Container. iu ny
c ngha rng trong v d ca chng ta ci JTable khng thc s cha bt c i tng no ca
JComboBox c. Thay vo , khi ci bng c v ln, mi mt s c nhim v v ra nhng g bn
trong n. iu ny c thc hin bng cch truyn mt i tng ca lp Graphics vo phng
thc paint ca renderer, v khi vng khng gian trong mt s c v ln. Vi cch trn, mt thnh
phn hin th c th v ln hu ht thm ch tt c cc ca bng thay v cp pht hn mt thnh phn
hin th cho ch mt , 100 s cn 100 thnh phn hin th v iu ny s tn nhiu b nh ca chng
ta hn.
Trong rt nhiu trng hp, phng php d nht nh ngha mt renderer l k tha
lpDefaultTableCellRenderer l renderer mc nh cho mt trong JTable. DefaultTableCellRenderer k
tha JLabel, v biu din cc gi tr cc i dng String. Dng biu din String ca mt i tng
c ly ra bng cch gi phng thc toString() ca i tng , v DefaultTableCellRenderer s
truyn biu din ny vo phng thc setText() m n k tha t lp JLabel. Cc hnh ng trn
c thc hin trong phng thc setValue(). Phng thc ny nhn mt tham s u vo l mt tham
chiu n gi tr ca ang c v.

public void setValue(Object value){
setText((value == null)? "" : value.toString());
}

Ni tm li DefaultTableCellRenderer n gin l mt JLabel vi ni dung l gi tr ca ang c v.
Trong rt nhiu trng hp, vic gi phng thc toString() khng phi l mt phng php thch hp
ly v dng biu din String cho gi tr ca mt . V d nh ct Account Balance trong v d ca
chng ta. Gi tr c hin th trong ct ny th ng nhng chng khng c nh dng ng khi m
bn thn chng ang biu din cc gi tr tin t. Tuy nhin, chng ta c th d dng khc phc vn
ny bng cch to ra mt TableCellRenderer ty bin v gn cho n nhim v v cc gi tr di dng
tin t. Ta t tn cho renderer l CurrencyRenderer v n nm trong fileCurrencyRenderer.java

public class CurrencyRenderer extends DefaultTableCellRenderer{
public CurrencyRenderer(){
super();
setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
}

@Override
public void setValue(Object value){
if((value != null) && (value instanceof Number)){
Number numberValue = (Number)value;
NumberFormat formater = NumberFormat.getCurrencyInstance();
value = formater.format(numberValue.doubleValue());
}
super.setValue(value);
}
}

Lp CurrencyRenderer thc hin hai vic, th nht n cn li l ngang cho ci JLabel trong sut qu
trnh khi to. Th hai l n ci t li phng thc setValue ca DefaultTableCellRenderer. Bi v
chng ta bit rng lp renderer ny s c s dng v cho cc c kiu d liu l s, cho nn
chng ta p kiu cho gi tr ca v kiu Number v sau nh dng li gi tr ny theo kiu tin t
bng vic s dng lp NumberFormat.
Nh vy l chng ta to mt renderer ty bin cho ct Account Balance, v chng ta cn phi s
dng renderer ny v cc cho ct . Chng ta c th thc hin iu ny bng cch trc tip gn
ci renderer n TableColumn ging nh chng ta lm trc y i vi ct Gender. Tuy nhin, vn
cn mt cch khc lm iu ny. Bn cnh vic kt hp mt renderer vi mt ct, chng ta cn c th
kt hp renderer vi mt kiu d liu ring bit no . Khi , trong bng, cc cc ct c chung
kiu d liu s c v ch bi mt renderer.
Khi JTable c khi to, n to mt nh x gia cc kiu v cc renderer. N s dng nh x ny
chn ra renderer s v cho cc trong cc ct trong trng hp m cc renderer cho cc ct khng
c ch ra mt cch tng minh. Hay ni cch khc nu chng ta khng ch ra mt cch trc tip mt
renderer cho mt ct no ging nh lm vi ct Gender th JTable s t chn ra renderer da trn
kiu d liu c lu trong ct . N xc nh kiu d liu cho cc ct bng vic gi phng
thc getColumnClass trong TableModel. Tuy nhin, phng thc getColumnClass() trong
AbstractTableModel mc nh coi tt c cc ct ca bng s c kiu l Object.

public Class getColumnClass(int columnIndex){
return Object.class;
}

Bi v AbstractTableModel mc nh khng th bit c c th kiu ca cc ct, cho nn ch c mt gi
thuyt an ton l n coi tt c cc u c kiu l Object. Tuy nhin, trong thc t, cc s hu ht
s cha cc gi tr c kiu l lp con ca lp Object chng hn nh Float, Date, V vy, nu chng ta
mun bng c kh nng xc nh c mt kiu ring bit cho mt ct ca n, chng ta phi ci t li
phng thc getColumnClass() trong TableModel ca chng ta. Cho v d, bi v tt c cc gi tr trong
ct Account Balance c kiu l Float, nn chng ta c th ci t li phng thc getColumClass() trong
lp TableValues nh sau:

public class TableValues extends AbstractTableModel{

public final static int FIRST_NAME = 0;
[...]

public Object[][] values = {
[...]
};

public int getRowCount() {
return values.length;
}

public int getColumnCount() {
return values[0].length;
}

public Object getValueAt(int rowIndex, int columnIndex) {
return values[rowIndex][columnIndex];
}

@Override
public String getColumnName(int column){
return columnNames[column];
}

@Override
public Class getColumnClass(int column){
Class dataType = super.getColumnClass(column);
if(column == ACCOUNT_BALANCE){
dataType = Float.class;
}
return dataType;
}
}

By gi JTable c th xc nh c rng ct Account Balance c kiu l Float. By gi chng ta cn
kt hp CurrencyRenderer vi kiu d liu ny bng vic gi phng thc setDefaultRenderer()trong
contructor ca lp SimpleTableTest

public class SimpleTableTest extends JFrame{
protected JTable table;

public SimpleTableTest(){
[...]
tc.setCellRenderer(new GenderRenderer());
table.setDefaultRenderer(Float.class, new CurrencyRenderer());
JScrollPane jsp = new JScrollPane(table);
pane.add(jsp, BorderLayout.CENTER);
}

public static void main(String [] args){
[...]
}
}

Vi dng lnh mu vng trn, CurrencyRenderer tr thnh renderer mc nh cho tt c cc ct c kiu
d liu l Float trong bng. V vy, CurrencyRenderer tr thnh renderer cho ct Account Balance. Sau
khi chy chng trnh ta thy gi tr trong ct Account Balance c nh dng l tin t ging nh hnh
di y:

By gi, iu g s xy ra nu nh chng ta khng trc tip gn mt renderer cho mt ct v cng khng
c mt nh x no t mt renderer n kiu d liu ca ct . Khi , JTable s thc hin vic i d
trn da trn s k tha ca kiu d liu trong ct bng vic tm kim mt nh x t renderer n kiu
cha ca kiu . Cho v d, nu phng thc getColumnClass ch ra rng ct c kiu l Float nhng
khng c renderer no c ch ra cho kiu Float c, khi JTable s tm kim xem c renderer no
c ch ra cho kiu cha ca kiu Float l kiu Number hay khng. Nu vn khng c mt renderer no
c ch ra cho kiu Number, JTable s tm kim mt renderer cho kiu Object l kiu cha ca kiu
Number. n y th n tm ra mt renderer cho ct , chnh l DefaultTableCellRenderer theo mc
nh.
Vy tng kt li, mt JTable s tm kim mt renderer cho cc ct ca n theo cc bc nh sau:
1. Nu mt renderer c t trc tip cho mt ct (ct Gender), s s dng lun renderer
2. Ly v kiu ca cc ct bng vic gi phng thc getColumnClass ca TableModel
3. Nu c mt renderer no c ch nh i vi mt kiu, s s dng renderer cho tt c cc ct c kiu
d liu (ngoi tr nhng ct c ch nh trc tip trn)
4. Nu khng c renderer no c ch nh cho mt kiu, s thc hin tm kim renderer cho kiu cha ca
kiu , c lp li nh th cho n khi tm ra mt renderer th dng li
Cc renderer mc nh ca JTable
Theo nh trn, chng ta bit to ra mt renderer ty bin ca chng ta nh th no v lm sao kt
hp mt renderer n mt kiu d liu no . Tuy nhin, thng th chng ta cng khng cn lm
nh th bi v JTable cung cp sn cho chng ta mt tp cc renderer c nh ngha trc cho
mt s kiu d liu thng dng v s t ng c thm vo nh x t renderer n kiu d liu. Mt v
d chng ta tng ni l c mt s kt hp gia kiu Object v DefaultTableCellRenderer. Ngoi ra,
cn c cc renderer cho cc kiu d liu khc na. iu ny c ngha rng, nu mt trong cc renderer
c sn ny c th dng c trong bng ca chng ta, th tt c nhng g chng ta cn lm ch l ch ra
kiu d liu cho cc ct ca bng trong phng thc getColumnClass(). Nh vo , JTable s bit cch
s dng cc renderer c sn theo tng ng vi kiu d liu cc ct. Trong v d ca chng ta,
chng ta c th s dng renderer c sn cho kiujava.util.Date lm renderer cho ct Date of Birth. Tt
c nhng g chng ta cn lm l thm nhng dng mu vng sau vo phng thc getColumnClass()
trong lp TableValues nh sau.

public class TableValues extends AbstractTableModel{

public final static int FIRST_NAME = 0;
[...]

public Object[][] values = {
[...]
};

public int getRowCount() {
return values.length;
}

public int getColumnCount() {
return values[0].length;
}

public Object getValueAt(int rowIndex, int columnIndex) {
return values[rowIndex][columnIndex];
}

@Override
public String getColumnName(int column){
return columnNames[column];
}

@Override
public Class getColumnClass(int column){
Class dataType = super.getColumnClass(column);
if(column == ACCOUNT_BALANCE){
dataType = Float.class;
}else if(column == DATE_OF_BIRTH){
dataType = java.util.Date.class;
}
return dataType;
}
}

By gi chy chng trnh chng ta s thy gi tr trong ct Date of Birth s hin th ng theo nh dng
ngy sinh nh hnh di y:

Ngoi ra cn cc renderer cho cc kiu d liu khc nh sau:
java.lang.Number
y l kiu cha cho cc kiu s nh Integer, Float, Long Ci renderer c nh ngha i vi kiu
Number l mt lp con ca lp DefaultTableCellRenderer v n cn l cho gi tr lch sang bn phi
ging nh chng ta lm trong CurrencyRenderer. Ni cch khc, renderer cho kiu Number biu din
gi tr di dng String, nhng khc vi mc nh l n cn l sang bn phi thay v bn tri nh mc
nh. Chng hn nh ta p dng n vi ct Account Balance th s ging nh hnh di y

javax.swing.ImageIcon
Renderer kt hp vi lp ny cho php chng ta hin th mt Icon ln trn bng ca chng ta. Renderer
ny chnh l DefaultTableCellRenderer v n khai thc tnh nng ca mt JLabel l c th hin th c ch
v nh. Thay v hin th ch, n s hin th hnh nh cho cc trong ct c kiu d liu l ImageIcon.
java.lang.Boolean
Khi renderer ny c s dng, n s hin th ni dung cho cc trong cc ct c kiu l Boolean di
dng cc JCheckBox. Cc JCheckBox ny s trng thi c nh du nu gi tr cc l true
v khng c nh du nu gi tr cc l false. Hnh di y minh ha iu ny khi ta p dng
n cho ct Gender trong v d.

n y, c v nh chng ta bit cch hin th mi th ln ci bng ca chng ta. Tuy nhin, vic
s dng bng khng ch dng li mc hin th thng tin. Chng ta cn mun c th trc tip sa
thng tin trn cc ca bng. iu ny s c ni mt cch c th trong phn 4.

Trong phn 3, chng ta bit cch hin th d liu ln trn bng. Trong phn ny, chng ta s hc
cch sa gi tr trong mt ca bng.
Tr li v d ca chng ta mc d cc trong ct Gender u hin th mt JComboBox, tuy nhin chng
ta khng th thay i gi tr trong cc ny. Vi nhng g ang c, khng no ca bng trong v d l
c th sa c. Khi chng ta nhp chut trn mt , ton b dng s c chn thay v ch mt
m chng ta mun sa i. thay i iu ny, chng ta phi ci t li phng
thcisCellEditable() trong TableModel bi v ci t mc nh ca phng thc ny lun tr v gi tr l
false. Chng ta thay i lp TableValues nh sau:

public class TableValues extends AbstractTableModel{

public final static int FIRST_NAME = 0;
[...]

public Object[][] values = {
[...]
};

public int getRowCount() {
return values.length;
}

public int getColumnCount() {
return values[0].length;
}

public Object getValueAt(int rowIndex, int columnIndex) {
return values[rowIndex][columnIndex];
}

@Override
public String getColumnName(int column){
return columnNames[column];
}

@Override
public Class getColumnClass(int column){
[...]
}

@Override
public boolean isCellEditable(int row, int column){
if(column == GENDER){
return true;
}
return false;
}
}


Bng vic sa i nh trn, cc trong ct Gender gi y c th sa c. Tuy nhin nu chng ta
nhp chut n vo mt trong ct chng ta li c thm cht ngc nhin bi v khng c iu g xy
ra ngoi tr c dng c chn. Trong khi , ci m chng ta mong ch l c th chn mt gi tr
khc t mt JComboBox. Nu chng ta kch p chut vo , mt JTextField xut hin v trong n l
gi tr kiu Boolean ca Gender (true hoc false), v chng ta c th sa gi tr ny trong JTextField
ging nh hnh di y:

Ti sao li l mt JTextField m li khng phi l mt JComboBox. gii thch iu ny chng ta phi
nh rng cc trong bng khng thc s cha bt c mt thnh phn no. Cc ch n gin l c
v bi cc renderer v trong trng hp ny cc trong ct Gender c v nh l cc JComboBox.
Qu trnh sa i gi tr trong cc l mt qu trnh hon ton tch ri ring bit v n c th c x l
bi mt thnh phn ging nh l thnh phn c v bi renderer. V d, thnh phn hin th mc nh
cho mt JTable l mt JLabel trong khi thnh phn sa i mc nh ca n l mt JTextField v y l
l do ti sao JTextField li xut hin khi m chng ta chn sa mt trong ct Gender.
Bt k l thnh phn no c s dng, mc tiu cui cng vn l lm sao cho gi tr trong mt c
th thay i c. Tuy nhin trong trng hp ca chng ta gi tr sau khi c sa i s b loi b v
li quay tr v gi tr ban u. hiu ti sao iu ny li xy ra v chng ta phi lm nhng g, trc
ht chng ta hy lm quen vi khi nim editor cho mt v bit cch mt JTable x l s thay i gi tr
trong cc ca n nh th no.
Editor cho mt trong JTable
Ging nh renderer iu khin cch hin th gi tr ca mt , editor x l khi m gi tr trong c
sa i. Editor c th ni l phc tp hn so vi renderer mt cht nhng n so vi renderer th cng c
nhiu im tng ng nh sau:
Mt editor c th gn ti mt hay nhiu i tng ca lp TableColumn
Mt editor c th gn ti mt hay nhiu kiu d liu v s c s dng lm editor ca cc ct c kiu
d liu trong trng hp khng c mt editor no c ch nh trc tip kt hp vi cc ct .
Cc thnh phn hin th c th c s dng trong qu trnh chnh sa, ging nh cch m chng c s
dng bi cc renderer. Trong thit k thc t, mt renderer v mt editor cho mt ca bng thng s
dng chung mt thnh phn hin th.
Chng ta c th gn editor n mt i tng ca TableColumn hoc n mt kiu d liu bng cch ln
lt s dng phng thc setCellEditor() trong TableColumn hoc phng thcsetDefaultEditor() trong
JTable. Vic ci t interface TableCellEditor th phc tp hn so vi trng hp ci t
TableCellRenderer v hiu c cc phng thc trong TableCellEditor, chng ta hy tm hiu editor
tng tc vi JTable nh th no.
Khi mt JTable pht hin ra mt thao tc nhp chut trn mt , n gi phng thc isCellEditable()
trong TableModel. Nu phng thc ny tr v mt gi tr l false th khi c ngha l khng th
sa c v qu trnh x l dng y, khng lm thm bt c g khc na. Trong trng hp phng
thc ny tr v gi tr l true th sau JTable s nhn din editor ca ny v gi phng
thc isCellEditable() ca editor. Mc d TableModel v CellEditor u c phng thc l isCellEditable(),
nhng gia chng c mt s khc bit. Phng thc trong TableModel ch ly gi tr ca ch s ct v
ch s dng lm tham s u vo, trong khi , phng thc trong CellEditor ly tham s u vo l mt
i tng ca EventObject biu din cho s kin kch chut. Chng ta c th s dng i ng ny
ly ra s ln kch chut trong s kin. Mt phi c kch p trc khi chng ta c th sa n, v
chng ta quan st hin tng ny trong ct Gender ca v d. Ni mt cch khc phng thc
isCellEditable() tr v mt gi tr l false khi m s ln kch chut l 1, v s tr v l true nu nh s ln
kch chut ln hn 1.
Chng ta c th thc hin sa i gi tr cho mt khi v ch khi c hai phng thc isCellEditable() trn
u tr v gi tr l true. Khi trng hp ny xy ra, qu trnh sa i c khi to bng vic gi
phng thc getTableCellEditorComponent(). Phng thc ny gm nhng tham s u vo sau:
Mt tham chiu n JTable ca ang c sa
Mt tham chiu n gi tr hin thi ca
Mt bin boolean xc nh xem c c chn hay khng
Ch s hng ca ang c sa
Ch s ct ca ang c sa
Cc tham s trn tng t vi cc tham s u vo trong phng thc
getTableCellRendererComponent() trong TableCellRenderer. S khc bit duy nht y chnh l
phng thc getTableCellEditorComponent() khng c mt tham s u vo kiu boolean ch ra
c phi l mt nhp d liu v ang c tr n hay khng, bi v ci ny c th t suy din ra
lun l true khi m ang trng thi c sa.
Trc khi tr v mt tham chiu n thnh phn hin th cho vic x l chnh sa, phng thc
getTableCellEditorComponent() phi thc hin khi to sao cho gi tr th hin trn thnh phn phi
trng khp vi gi tr hin thi ca . Gi su, chng ta ang to mt editor cho php ngi s
dng chn gi tr cho ct Gender l Male hoc Female t mt JComboBox. Trong trng hp , chng
ta cn phi khi to JComboBox sao cho ban u gi tr c chn trong n phi ging vi gi tr hin
thi ca cc trong ct Gender.
Sau khi thnh phn tham chiu c tr v t phng thc getTableCellEditorComponent(), JTable
s t kch thc v v tr cho thnh phn sao cho n trc tip nm trng khp ln ang c
sa. iu ny lm cho ta tng rng ang thc s trng thi chnh sa nhng thc ra l cc thao
tc chnh sa ch thc hin trn mt thnh phn nm pha trn ci .
Vic t thnh phn dng cho vic chnh sa bn trn mt cng c ngha l s kin khi to qu trnh
chnh sa c truyn vo thnh phn ny. V d, trong trng hp mt editor dng JComboBox cho
vic chnh sa th s kin kch chut c truyn vo JComboBox. Chnh v th khi kch chut vo mt
chnh sa cng c ngha l JComboBox cng nhn s kin ny v n s s ra mt ca s vi nhiu
la chn. Chng ta chn mt trong s chng cng bng thao tc kch chut. Cui cng ca qu trnh ny,
khi phng thc shouldSelectCell() ca editor c truyn vo s kin kch chut trn v tr v gi tr l
true th y l lc vic chnh sa kt thc.
Mi mt editor cn phi ci t phng thc addCellEditorListener() vremoveCellEditorListener(), v
interface CellEditorListener c nh ngha hai phng thc leditingStopped() v editingCanceled(). Trong
thc t, listener thng chnh l bn thn JTable, n s c thng bo khi m vic chnh sa mt
dng li hoc hy b. Thm vo na, editor cn phi ci t hai phng thc na
l cancelCellEditing() v stopCellEditing(). Hai phng thc ny ln lt gi hai phng
thc editingCanceled() v editingStopped() ca listener ng k.
Mt yu cu kt thc vic chnh sa cho mt c th bt ngun t JTable cha hoc t ngay
chnh bn thn editor. Ly v d, gi s chng ta kch chut vo mt v bt u chnh sa gi tr ca
n. Nu sau chng ta kch sang mt th hai khc, th JTable s gi phng
thcstopCellEditing() trong editor ca th nht trc khi n khi to qu trnh chnh sa cho th hai.
Mt editor hon ton c th dng vic chnh sa khi mt s kin no xy ra ch nh vic chnh sa
hon tt. Cho v d, khi s dng mt JComboBox nh mt editor, nu n nhn mt thng ip
t ActionEvent th n ngm nh rng y l du hiu chng ta va thc hin chn mt gi tr v kt thc
qu trnh chnh sa. Tng t nh vy, mt JTextField nhn mt tn hiu dng vic chnh sa
chnh l khi phm Enter c bm.
Bt k l cc yu cu cho vic dng chnh sa c sinh ra u th phng thc editingStopped() ca
JTable vn c c gi bi v n thuc v mt CellEditorListener c ng k. Trong phng thc
ny, JTable gi phng thc getCellEditorValue() ca editor ly v gi tr mi trong c chnh sa
sau truyn gi tr ny vo phng thc setValueAt() trong TableModel ca JTable. iu ny c ngha
rng, gi tr mi ca c ly v t editor v c gi n model c th c lu tr.
Tr v vi v d, gi ta to mt editor t tn l GenderEditor cho ct Gender. Editor ny s dng mt
JComboBox cho php chng ta c th chn mt trong hai gi tr l Male hoc Female trong ct
Gender. To lp GenderEditor trong file GenderEditor.java nh sau

public class GenderEditor extends JComboBox implements TableCellEditor{

protected EventListenerList listenerList = new EventListenerList();
protected ChangeEvent changeEvent = new ChangeEvent(this);

public GenderEditor(){
super();
addItem("Male");
addItem("Female");
addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {
fireEditingStopped();
}
});
}

public void addCellEditorListener(CellEditorListener listener){
listenerList.add(CellEditorListener.class, listener);
}

public void removeCellEditorListener(CellEditorListener listener){
listenerList.remove(CellEditorListener.class, listener);
}

protected void fireEditingStopped(){
CellEditorListener listener;
Object[] listeners = listenerList.getListenerList();
for(int i=0; i<listeners.length; i++){
if(listeners[i] == CellEditorListener.class){
listener = (CellEditorListener) listeners[i+1];
listener.editingStopped(changeEvent);
}
}
}

protected void fireEditingCanceled(){
CellEditorListener listener;
Object[] listeners = listenerList.getListenerList();
for(int i=0; i< listeners.length; i++){
if(listeners[i] == CellEditorListener.class){
listener = (CellEditorListener) listeners[i+1];
listener.editingCanceled(changeEvent);
}
}
}

public void cancelCellEditing(){
fireEditingCanceled();
}

public boolean stopCellEditing(){
fireEditingStopped();
return true;
}

public boolean isCellEditable(EventObject event){
return true;
}

public boolean shouldSelectCell(EventObject event){
return true;
}

public Object getCellEditorValue(){
return new Boolean(getSelectedIndex() == 0 ? true : false);
}

public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int
column){
boolean isMale = ((Boolean) value).booleanValue();
setSelectedIndex(isMale?0:1);
return this;
}
}

Khi vic chnh sa c kch hot trong mt no ca ct Gender, phng thc
getTableCellEditorComponent() c gi, editor lc ny chun b trng thi cho n trc khi hin th.
Trong trng hp ny, gi tr Male hoc Female s c chn da trn gi tr hin ti ca ang c
chnh sa. Khi chng ta chn mt gi tr trong JComboBox, phng thc fireEditingStopped() c gi,
v n thng bo vi JTable rng qu trnh chnh sa kt thc. JTable sau s gi phng thc
getCellEditorValue() ly v gi tr mi ca v s truyn gi tr ny vo phng thc setValueAt()
ca TableModel.
Tip theo chng ta sa li lp SimpleTableTest trong file SimpleTableTest.java nh sau:

public class SimpleTableTest extends JFrame{
protected JTable table;

public SimpleTableTest(){
[...]
TableColumnModel tcm = table.getColumnModel();
TableColumn tc = tcm.getColumn(TableValues.GENDER);
tc.setCellRenderer(new GenderRenderer());
tc.setCellEditor(new GenderEditor());
table.setDefaultRenderer(Float.class, new CurrencyRenderer());
JScrollPane jsp = new JScrollPane(table);
pane.add(jsp, BorderLayout.CENTER);
}

public static void main(String [] args){
[...]
}
}

Khi chy chng trnh ta s thy khi kch vo mt trong ct Gender chnh sa, mt ca s c s
xung vi gi tr c bi en chnh l gi tr hin thi ca .

cho sau khi chn gi tr ny thc s c thay i hn th chng ta cn phi ci t li phng thc
setValueAt() trong lp TableValues nh sau

public class TableValues extends AbstractTableModel{

public final static int FIRST_NAME = 0;
[...]

public Object[][] values = {
[...]
};

public int getRowCount() {
return values.length;
}

public int getColumnCount() {
return values[0].length;
}

public Object getValueAt(int rowIndex, int columnIndex) {
return values[rowIndex][columnIndex];
}

@Override
public String getColumnName(int column){
return columnNames[column];
}

@Override
public Class getColumnClass(int column){
[...]
}

@Override
public boolean isCellEditable(int row, int column){
[...]
}

@Override
public void setValueAt(Object value, int row, int column){
values[row][column] = value;
}
}

DefaultCellEditor
Chng ta cng khng nht thit trong mi trng hp u phi t xy dng mt editor hon ton mi.
Trong thc t, lp DefaultCellEditor cho php chng ta d dng to mt editor s dng mt JCheckBox,
JComboBox, hoc l JTextField. Tt c mi th phi lm l to mt i tng ca lp DefaultCellEditor
v sau truyn cho n cc i tng ca mt trong 3 thnh phn hin th k trn vo. Tuy nhin,
DefaultCellEditor khng c tnh mm do v trong nhiu trng hp chng ta vn phi to editor ca
ring chng ta.
Nh vy trong phn 4, chng ta bit cch chnh sa d liu ngay chnh trn ci bng ca chng ta.
Cc thao tc chn thc hin trn hng v ct trong mt bng s c gii thiu trong phn 5.

Trong phn ny, chng ta tp trung vo mt s thit lp lm vic vi cc thao tc chn trn mt bng.
JTable l mt thnh phn hai chiu (hng v ct): mi c chn s c ch s hng v ch s ct.
Trong khi , JList l mt thnh phn mt chiu m mi mt ch c duy nht mt ch s l ch
s hng. Bi v bn cht ca JTable l mt thnh phn hai chiu cho nn thng tin c chn ca bng
khng th c qun l bi mt ListSelectionModel. Interface ListSelectionModel ch h tr cho vic qun
l cc thng tin c chn hnh thc mt chiu. khc phc vn ny, Jtable s dng hai i
tng ca lp DefaultListSelectionModel.
Mt i tng c qun l bi chnh bn thn Jtable. i tng ny qun l thng tin c chn theo
dng
Mt i tng c qun l bi TableColumnModel. i tng ny qun l thng tin c chn theo ct
Nh chng ta ni lc trc, khi mt c chn, cc khc cng c th c chn theo. iu ny
ty thuc vo vic chng ta thit lp cch chn cho bng. Trong thc t, c rt nhiu thit lp chn cho
mt bng. Interface ListSelectionModel v lp ci t ca n l DefaultListSelectionModel c s dng
qun l vic chn trn mt JTable.
Chn theo hng: Khi mt c chn th tt c cc khc cng hng vi n cng c chn. y l thit
lp chn mc nh ca JTable. JTable cung cp cho chng ta hai phng thc
l getRowSelectionAllowed() v setRowSelectionAllowed() cho php chng ta truy vn, thit lp, hoc
hy b c ch chn theo hng cho bng.
Chn theo ct: Khi mt c chn, tt c cc khc cng ct vi n cng c chn. Vic truy vn,
thit lp, hy b c ch chn theo ct cho bng c thc hin bi hai phng
thcgetColumnSelectionAllowed() v setColumnSelectionAllowed() ca JTable
Chn theo : Trong ch ny, vic chn mt s khng nh hng g n cc khc. Vic truy vn,
thit lp, hy b c ch chn theo cho bng c thc hin bi hai phng
thcgetCellSelectionEnabled() v setCellSelectionEnabled() ca JTable. Vic kch hot ch chn theo
s lm v hiu ha hai ch l chn theo hng v chn theo ct
Kt hp cc ch chn theo hng, chn theo ct v chn theo
Chng ta c th s dng ch chn theo hng v chn theo ct cng nhau sao cho khi chng ta nhp
chut chn mt , tt c cc khc trong cng hng hoc ct vi n cng c chn. Tuy nhin vic
kch hot ch chn theo s dn n vic cc ch chn theo hng v chn theo ct b mt hiu
lc. Cho v d, gi s chng ta c on m sau:

JTable table;
...
table.setRowSelectionAllowed(true);
table.setColumnSelectionAllowed(true);
table.setCellSelectionEnabled(true);

Trong on m trn, mc d tt c cc ch chn ca bng u c kch hot tuy nhin vic kch
hot ch chn theo s v hiu ha hai ch kia. V th, mc d chng ta c ba loi thit lp ch
chn cho bng, nhng ch c bn t hp ca chng l c ngha:
Ch c ch chn theo hng c kch hot
Ch c ch chn theo ct c kch hot
Ch chn theo c kch hot. Khi chng ta khng cn quan tm n vic hai ch cn li c
c kch hot hay khng
Khi m tt c cc ch chn b v hiu ha.
Trong trng hp cui cng, khi m tt c cc ch b v hiu ha, chng ta khng th chn bt k mt
no trong bng.
Cc ch chn theo danh sch
Khi mt c chn, lc mt hoc c hai i tng ca ListSelectionModel s c cp nht theo
vic chn ny. Theo mc nh, mi model c th duy tr nhiu khong gi tr. Cho v d, nh hnh di
y, trong model s duy tr hai khong gi tr c chn. Khong gi tr th nht l cc dng trong bng
c ch s t 0 n 1 v khong gi tr th hai l cc dng trong bng c ch s t 3 n 4.

chn ra hai khong gi tr ging nh trn, chng ta lm cc bc nh sau:
1. Chn dng trn cng ca bng
2. Bm v gi phm Shift sau nhp chut chn dng th hai. Nh vy n y, khong th nht ca cc
dng c chn
3. Th phm Shift sau bm v gi phm Ctrl, chn dng th t
4. Th phm Ctrl, bm v gi phm Shift sau nhp chut chn dng cui cng. Lc ny, khong th hai ca
cc dng c chn
Nh chng ta lm pha trn, chn mt khong gi tr gia hai cp gi tr, chng ta ch vic chn
im u khong gi tr sau bm v gi phm Shift ri chn im cui khong gi tr . Trong khi
vic bm phm Ctrl s cho php chng ta chn mt gi tr khc nhng khng lm mt i nhng gi tr hay
khong gi tr c chn trc . Mt cch chn khc thay v s dng phm Shift chn mt
khong gi tr l nhp chut ln ri ko th con tr trn khong gi tr . Cho v d, trong trng hp
ny, chng ta c th nhp chut ln mt ca dng u tin v sau ko th chut n dng th hai,
nh vy khong gi tr u tin trong bng s c chn.
V d trn minh ha cho ch chn mc nh gi l multiple-interval selection hay l c th chn
nhiu khong gi tr. y l mt trong ba ch m ListSelectionModel h tr. Hai ch cn li
l single-interval selection v single selection.
Nh ci tn ch ra, ch single-interval selection l ch cho php chn mt khong gi tr n l.
Trong v d ca chng ta, nu chng ta chn ch single-interval selection th sau khi khong gi tr th
hai (t ch s hng 3 n 4) c chn, khong gi tr th nht (t ch s hng 0 n 1) c chn trc
s tr thnh khng c chn.
Cn trong ch single-selection, mt ListSelectionModel ch cho php chn mt gi tr n l v khng
th chn mt khong gi tr trong bng. Cho v d, khi chng ta kch hot ch chn theo ct v single-
selection, chng ta ch c th chn mt ct duy nht ti mt thi im.
Nh ni trc , mi JTable s duy tr hai i tng ca ListSelectionModel v cung cp phng
thc setSelectionMode() thit lp ch chn theo danh sch cho c hai i tng . Mi mt ch
chn s c biu din bi mt gi tr hng s c nh ngha trong ListSelectionModel:
MULTIPLE_INTERVAL_SELECTION
SINGLE_INTERVAL_SELECTION
SINGLE_SELECTION
Ch rng JTable khng c phng thc getSelectionMode() ly v ch hin ti. Phng thc ny
thuc v i tng ca ListSelectionModel. Chng ta phi ly thng tin trn t i tng ca
ListSelectionModel nh cch sau:

JTable table;
...
int oldSlectionMode = table.getSelectionModel().getSelectionMode();
table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);

Tr li v d ca chng ta, minh ha cho cc ch chn v s kt hp gia chng, chng ta s sa
on m trong lp SimpleTableTest file SimpleTableTest.java nh sau:

public class SimpleTableTest extends JFrame{
protected JTable table;

public SimpleTableTest(){
[...]
pane.add(jsp, BorderLayout.CENTER);

JPanel outerPanel = new JPanel();
outerPanel.setLayout(new GridLayout(1, 2, 0, 0));
JPanel innerPanel = new JPanel();
innerPanel.setLayout(new FlowLayout());
JCheckBox modeBox = new JCheckBox("Row", true);
modeBox.addItemListener(new ItemListener() {

public void itemStateChanged(ItemEvent event) {
JCheckBox box = (JCheckBox)(event.getSource());
table.setRowSelectionAllowed(box.isSelected());
}
});
innerPanel.add(modeBox);
modeBox = new JCheckBox("Column");
modeBox.addItemListener(new ItemListener() {

public void itemStateChanged(ItemEvent event) {
JCheckBox box = (JCheckBox)(event.getSource());
table.setColumnSelectionAllowed(box.isSelected());
}
});
innerPanel.add(modeBox);
modeBox = new JCheckBox("Cell");
modeBox.addItemListener(new ItemListener() {

public void itemStateChanged(ItemEvent event) {
JCheckBox box = (JCheckBox)(event.getSource());
table.setCellSelectionEnabled(box.isSelected());
}
});
innerPanel.add(modeBox);

BevelBorder bb = new BevelBorder(BevelBorder.RAISED);
TitledBorder tb = new TitledBorder(bb, "Table Selection Types");
innerPanel.setBorder(tb);
outerPanel.add(innerPanel);

innerPanel = new JPanel();
innerPanel.setLayout(new FlowLayout());
JComboBox listModes = new JComboBox();
listModes.addItem("Single Selection");
listModes.addItem("Single Interval Selection");
listModes.addItem("Multiple Interval Selections");
listModes.setSelectedIndex(2);
listModes.addItemListener(new ItemListener() {

public void itemStateChanged(ItemEvent event) {
JComboBox box = (JComboBox)(event.getSource());
int index = box.getSelectedIndex();
switch(index){
case 0:
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
break;
case 1:
table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
break;
case 2:
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
break;
}
}
});
innerPanel.add(listModes);
bb = new BevelBorder(BevelBorder.RAISED);
tb = new TitledBorder(bb, "List Selection Modes");
innerPanel.setBorder(tb);
outerPanel.add(innerPanel);

pane.add(outerPanel, BorderLayout.SOUTH);
}

public static void main(String [] args){
[...]
}
}

By gi chy li chng trnh v chng ta c th t t kim tra cc ch chn v t hp ca chng c
nh hng nh th no n vic chn d liu trong bng.

Thit lp vic chn bng dng lnh
Ngoi cc s kin do ngi s dng c th sinh ra thay i vic chn cc trong mt bng, JTable
cng cung cp cho chng ta mt s cc phng thc chng ta c th ly thng tin v sinh ra cc s
kin bng dng lnh. Cc phng thc s c lit k trong bng di y:
Phng thc Thc hin
getSelectedRowCount() Tr v s hng ang c chn trong bng
getSelectedRows()
Tr v mt mng cc s nguyn, mi mt s nguyn chnh l
ch s ca mt hng ang c chn trong bng.
getSelectedRow()
Tr v mt s nguyn, s nguyn ny l ch s nh nht ca
mt hng trong tp hp cc hng ang c chn ca bng.
setRowSelectionInterval(int index0,
int index1)
Chn mt tp cc hng c ch s t index0 cho n index1.
Cc hng khc c ch s khng thuc vo khong ny s
khng c chn k c khi chng c chn trc .
addRowSelectionInterval(int
index0,int index1) Chn mt tp cc hng c ch s t index0 cho n index1.
getSelectedColumnCount() Tr v s ct ang c chn trong mt bng
getSelectedColumns()
Tr v mt mng cc s nguyn, mi s nguyn l mt ch
s ca mt ct ang c chn trong bng
getSelectedColumn()
Tr v mt s nguyn l ch s nh nht ca mt ct trong s
cc ct ang c chn ca bng.
setColumnSelectionInterval(int
index0, int index1)
Chn cc ct c ch s nm trong khong t index0 n
index1. Cc ct khc c ch s nm ngoi khong ny s
khng c chn bt k trc chng c chn hay
cha.
addColumnSelectionInterval(int
index0, int index1)
Chn cc ct c ch s nm trong khong t index0 n
index1
Tt c cc phng thc ny c nh ngha trong JTable. Khi mt phng thc c gi n s chuyn
yu cu n mt ListSelectionModel x l v ly thng tin . Mt cch c th, cc phng thc c
lin quan n vic chn theo hng s chuyn yu cu v mt model c qun l bi JTable, trong khi
cc phng thc lin quan n vic chn theo ct s chuyn yu cu v mt model c qun l bi
mt ci t ca TableColumnModel trong bng.
Nh vy kt thc phn ny, chng ta nm c cc ch chn khi thao tc vi hng v ct.
Trongphn 6 chng ta s tm hiu v cc thao tc vi tiu ca bng.

Nh gii thiu phn 5, trong phn ny, chng ta s hc cch s dng v thao tc vi cc tiu
trong mt bng. Mi ct trong mt bng u cn phi c mt tiu gip ngi s dng hnh dung ra
cc gi tr trong ct l biu hin ci g. Trong phn 2 ca lot bi vit v JTable ny, chng ta
c bit lm sao to tiu cho cc ct trong bng v phn ny, s b sung thm nhng iu th v
khi thao tc vi cc tiu trong mt bng.
Vic to ra tiu cho cc ct trong mt bng khng cn xa l vi chng ta. Tuy nhin vic to ra cc
tiu nh th ch gip v mt hin th v khng h c mt chc nng g khc na. Chng hn nh
chng chng c phn ng g khi chng ta nhp chut vo chng, hoc on ch cho tiu ch c th
nm trn mt dng duy nht.
Khi thit k giao din, s c lc chng ta cn i hi cc chc nng khc na t cc tiu ny. Cho v
d, chng ta c th lm mt tooltip miu t r hn v mi tiu , hoc cho php mt ct c th c
chn v t ng sp xp theo th t gim dn hoc tng dn ca cc gi tr trong mt ct bng vic
nhp chut vo tiu , hoc cho php on ch trong tiu cho th c ngt ra lm nhiu dng.
Cc chc nng ny hon ton c th lm c nu chng ta nm vng v cch lm vic ca cc tiu
trong JTable.
V tiu
tiu cho mt ct trong bng cng ging nh cc d liu khc, c v nn bi cc renderer.
Renderer mc nh cho mt trong bng s k tha t mt JLabel v tiu cng khng ngoi l. Mt
renderer cho mt tiu ca mt ct c th c ly ra t phng thc getHeaderRenderer()ca i
tng TableColumn tng ng vi ct . Cho v d, on m sau s ly ra mt tham chiu n
renderer ca tiu cho ct th hai trong mt bng:

JTable table;
[...]
TableColumnModel tcm = table.getColumnModel();
TableColumn tc = tcm.getColumn(1);
TableCellRenderer tcr = tc.getHeaderRenderer();

Ngoi kh nng c th ly v mt renderer cho tiu ca mt ct nht nh, chng ta cn c th ch
nh mt renderer c th cho mt tiu ca ct . Trong v d ca chng ta, nu chng ta mun to
mt renderer gip on ch trong tiu ca mt ct c th hin th trn nhiu dng khc nhau, th
khi renderer phi k tha mt JPanel cha nhiu JLabel thnh cc dng thay v ch mt JLabel nh
mc nh. Bi v JLabel khng h tr vit mt on ch trn nhiu dng ging nh JPanel. Nh vy, u
tin ta phi to mt renderer c tn l MultiLineHeaderRenderer nm trong
fileMultiLineHeaderRenderer.java nh sau:

public class MultiLineHeaderRenderer extends JPanel implements TableCellRenderer{

public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
JLabel label;
removeAll();

StringTokenizer strtok = new StringTokenizer((String)value, "\r\n");
setLayout(new GridLayout(strtok.countTokens(), 1));
while(strtok.hasMoreElements()){
label = new JLabel((String)strtok.nextElement(), JLabel.CENTER);
LookAndFeel.installColorsAndFont(label,"TableHeader.background",
"TableHeader.foreground",
"TableHeader.font");
add(label);
}
LookAndFeel.installBorder(this, "TableHeader.cellBorder");

return this;
}
}


Renderer trn yu cu tn tiu ca ct phi cha cc k t nh \r (carriage return)
hoc \n(linefeed) nhng ch mun xung dng. Cho v d, ta thay i tiu cc ct trong lp
TableValues nh sau:

public class TableValues extends AbstractTableModel{

[...]
public final static boolean GENDER_FEMALE = false;
public final static String[] columnNames = {
"First Name", "Last Name", "Date of Birth", "Account\nBalance","Gender"
};

public Object[][] values = {
[...]
};

[...]
}

By gi ta t ci MultiLineHeaderRenderer va to trn lm renderer cho tiu ca cc ct trong
bng. Vic ny thc hin trong lp SimpleTableTest nh sau:

public class SimpleTableTest extends JFrame{
protected JTable table;

public SimpleTableTest(){
[...]
TableColumnModel tcm = table.getColumnModel();
TableColumn tc = tcm.getColumn(TableValues.GENDER);
tc.setCellRenderer(new GenderRenderer());
tc.setCellEditor(new GenderEditor());
MultiLineHeaderRenderer mlhr = new MultiLineHeaderRenderer();
tc = tcm.getColumn(TableValues.ACCOUNT_BALANCE);
tc.setHeaderRenderer(mlhr);
table.setDefaultRenderer(Float.class, new CurrencyRenderer());
JScrollPane jsp = new JScrollPane(table);
pane.add(jsp, BorderLayout.CENTER);

[...]
}

public static void main(String [] args){
[...]
}
}

Gi chy chng trnh chng ta c th thy tiu ca ct Account Balance s c ngt thnh hai
dng nh hnh i y:

t Tooltip cho tiu
Trong phn ny chng ta s hc cch thm tooltip vo trong tiu ca cc ct trong bng. Bi v chng
ta thng cho renderer k tha t cc thnh phn hin th, cc thnh phn hin th th c k tha t
lp JComponent, v th chng ta c th hon ton gi phng thc setToolTipText() t renderer ca mt
tiu t tooltip cho tiu . Tr li v d, gi chng ta mun t tooltip cho tiu ca ct
Account Balance, ta ch cn sa lp SimpleTableTest nh sau:

public class SimpleTableTest extends JFrame{
protected JTable table;

public SimpleTableTest(){
[...]
MultiLineHeaderRenderer mlhr = new MultiLineHeaderRenderer();
mlhr.setToolTipText("This is the person's current account balance");
tc = tcm.getColumn(TableValues.ACCOUNT_BALANCE);
[...]
}

public static void main(String [] args){
[...]
}

Gi chng ta chy chng trnh, khi di chuyn chut qua tiu t ca ct Account Balance, tooltip cho ct
ny s hin ln nh hnh di y:

y, chng ta s nhn ra mt vn c lin quan n s ch nh tooltip cho mt ct. v d ca
chng ta, chng ta ch gn mt renderer cho mt ct duy nht. Tuy nhin trong thc t th mt renderer
c th c gn cho nhiu ct trong mt bng. Hay ni cch khc, mt renderer c th c s dng
v cho rt nhiu trong bng v iu ny cng ng cho cc renderer ca tiu cc ct. Trong v d,
mt i tng ca lp MultiLineHeaderRenderer c th c s dng v cho cc tiu ca c ct
Account Balance ln ct Date of Birth. Tuy nhin, vic t tooltip th ch c th l duy nht cho mt ct m
thi. Nu nh ta cng s dng li renderer ca ct Account Balance cho ct Date of Birth th tooltip ca
ct Account Balance cng tr thnh tooltip ca ct Date of Birth v nh vy th hon ton khng thch
hp nh hnh di y:

C rt nhiu cch khc phc vn ny. Mt trong nhng cch d nht l gn cho cc ct cc i
tng renderer khc nhau. Chng hn, trong v d chng ta s gn renderer l hai i tng khc nhau
ca lp MultiLineHeaderRenderer cho hai ct Account Balance v Date of Birth. Ngoi ra, chng ta cn
c cch khc s c miu t sau.
JTableHeader
Tr li vi phn 1 ca lot bi vit ny, khi ta chy chng trnh v d, th bng hin ln khng c tiu
cho cc ct. Vn ny c khc phc trong phn 2 khi m JTable ca chng ta c thm vo mt
JScrollPane v phng thc getColumnName() trong model c ci t tr v tiu cho cc ct
trong bng. Tiu ca cc ct s t ng hin th khi m bng ca chng ta c hin th trong mt
JScrollPane v c th hn, chng c hin th trong vng gi l column header viewportca ca s
cun. Column header viewport l phn khng gian bn trn phn khng gian chnh ca mt
JScrollPane, v tt nhin, chng ta hon ton c th truy cp, chnh sa cc thnh phn c hin th
trong vng ny s dng hai phng thc l getColumHeader() v setColumnHeader() ca JScrollPane.
Cho v d, gi s chng ta mun hin th mt nt bm JButton trong phn column header viewport ca
ca s cun trong v d, chng ta c th tm thi sa lp SimpleTableTest nh sau:

public class SimpleTableTest extends JFrame{
protected JTable table;

public SimpleTableTest(){
[...]
table.setDefaultRenderer(Float.class, new CurrencyRenderer());
JScrollPane jsp = new JScrollPane(table){
public void setColumnHeaderView(Component comp){
super.setColumnHeaderView(new JButton("This is a JButton"));
}
};
pane.add(jsp, BorderLayout.CENTER);

[...]
}

public static void main(String [] args){
[...]
}
}

on m trn ci t li phng thc setColumnHeaderView() JScrollPane v iu ny dn ti vic
mt JButton c hin th trong phn column header viewport ca JScrollPane nh hnh di y:

Mc d chng ta thng khng c nhu cu s dng phng thc ny, nhng n ch ra rng, chng ta
c th s dng bt c thnh phn no lm thnh mt tiu . Mt cu hi t ra l, nu chng ta
khng ch ra r rng nh v d trn th mc nh thnh phn no s c s dng? Cu tr li l
mt i tng ca lp JTableHeader.
JTableHeader l mt thnh phn hin th cung cp cho chng ta cc hnh vi tng tc lin quan n
vic di chuyn v thay i kch thc cc ct ca mt JTable. Cho v d, trong phn 2 ca lot bi vit,
chng ta c cp v vic thay i kch thc ca mt ct trong bng, v y chnh l chng ta ang
tng tc vi mt i tng ca JTableHeader. Ngoi ra, chng ta cn c th xp xp li cc ct vo
cc v tr m chng ta mun bng cc nhp chut ln tng ct , gi chut tri ri ko th n v tr
chng ta mun. V cng l mt trong nhng chc nng m JTableHeader cung cp cho chng ta.
Mt trong nhng chc nng khc ca JTableHeader l tr v on ch tooltip khi m chng ta di chut
ln trn tiu ca mt ct no trong bng. Bn trn chng ta ni v vic sinh ra tooltip cho mt
ct l nh cc renderer, v chng ta cng c th ngc nhin l ti sao JTableHeader y li sinh ra
tooltip na? Nhng thc vy, chnh l JTableHeader sinh ra tooltip cho mt ct trong bng nhng ly
tooltip , n phi chuyn yu cu n renderer ca ct tng ng.
Khi phng thc getToolTipText() ca JTableHeader c gi, n c truyn vo mt tham s u vo
l mt MoustEvent cho php JTableHeader xc nh c tiu ca ct no ang c con tr
chut di chuyn qua. Sau , JTableHeader chn ra renderer tng ng vi ct ly on ch
tooltip tr v t renderer . Cch ny c v tt khi m mi tiu cho mi ct trong bng c mt
renderer ca ring n, nhng s khng thch hp khi m mt renderer c gn cho nhiu ct. khc
phc vn ny, ta to mt lp k tha t JTableHeader v trong n duy tr mt mng gm cc tooltip,
sau tr v tooltip ly ra t mng thay v phi gi n cc renderer. Chng ta to
lpJTableHeaderToolTips trong file JTableHeaderToolTip.java nh sau:

public class JTableHeaderToolTips extends JTableHeader{
protected String[] toolTips;
public JTableHeaderToolTips(TableColumnModel tcm){
super(tcm);
}

public void setToolTips(String [] tips){
toolTips = tips;
}

@Override
public String getToolTipText(MouseEvent event){
String tip = super.getToolTipText(event);
int column = columnAtPoint(event.getPoint());
if((toolTips != null) && (column < toolTips.length) && (toolTips[column] !=
null)){
tip = toolTips[column];
}
return tip;
}
}

By gi chng ta s dng lp JTableHeaderToolTips trong lp SimpleTableTest nh sau:

public class SimpleTableTest extends JFrame{
protected JTable table;

public SimpleTableTest(){
[...]
MultiLineHeaderRenderer mlhr = new MultiLineHeaderRenderer();
tc = tcm.getColumn(TableValues.ACCOUNT_BALANCE);
tc.setHeaderRenderer(mlhr);
JTableHeaderToolTips jthtt = new JTableHeaderToolTips(table.getColumnModel());
jthtt.setToolTips(new String[]{"Customer's First Name", "Customer's Last Name",
"Customer's Date of Birth", "Customer's Account Balance", "Customer's Gender"});
table.setTableHeader(jthtt);
table.setDefaultRenderer(Float.class, new CurrencyRenderer());
JScrollPane jsp = new JScrollPane(table);
pane.add(jsp, BorderLayout.CENTER);

[...]
}

public static void main(String [] args){
[...]
}
}

Gi chy chng trnh chng ta s c c cc tooltip trn cc tiu ca cc ct:

Chng ta c th lm nh trn l nh kh nng xc nh c ct no ang c con tr chut di
chuyn qua. lm nh vy chng ta phi s dng phng thc columAtPoint() c nh ngha trong
JTableHeader. Chng ta cng c th s dng k thut trn hin th tooltip cho cc khc trong bng.
Cc bc cng tng t, lm tooltip cho cc khc th chng ta phi ci t li phng
thc getToolTipText() ca JTableHeader, s dng hai phng thc l rowAtPoint() vcolumAtPoint()
nhn din ra v tr ca ang c con tr chut di chuyn qua.
Mt trng hp khc m chng ta vn phi s dng n JTableHeader l pht hin v s l cc
s kin chut xy ra trn cc tiu . Cho v d, gi s ng dng ca chng ta cho php ngi s dng
chn mt ct ca bng bng vic kch vo tiu ca ct . Mc nh th JTable khng cho php chng
ta lm iu ny, v vy, chng ta s phi t tay bt v x l s kin nhp chut. Trong trng hp yu
cu cho tooltip, yu cu ny s c chuyn n renderer ca ct tng ng. Tuy nhin, trong trng
hp ny ca chng ta th khng ging nh vy, c th bt c s kin chut, chng ta phi ng k
mt listener cho JTableHeader. Chng ta chnh sa lp SimpleTableTest trong
fileSimpleTableTest.java nh sau:

public class SimpleTableTest extends JFrame{
protected JTable table;

public SimpleTableTest(){
[...]
table = new JTable(tv);
table.setRowSelectionAllowed(false);
table.setColumnSelectionAllowed(true);
TableColumnModel tcm = table.getColumnModel();
[...]
JScrollPane jsp = new JScrollPane(table);
pane.add(jsp, BorderLayout.CENTER);
addHeaderListener();

JPanel outerPanel = new JPanel();
[...]
}

public void addHeaderListener(){
table.getTableHeader().addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent event){
JTableHeader header = (JTableHeader)(event.getSource());
int index = header.columnAtPoint(event.getPoint());
table.setColumnSelectionInterval(index, index);
}
});
}

public static void main(String [] args){
[...]
}
}

By gi chy chng trnh, khi chng ta nhp chut vo tiu ca ct Date of Birth, c ct s c
chn nh hnh di y:

Nh vy, trong phn ny chng ta tm hiu v cc thao tc khi lm vic vi tiu ca cc ct trong
bng. Chng ta c th ty bin thit k tiu v lm cho n thm phong ph vi cc tnh nng tng
tc vi ngi dng qua cc s kin chut. Trong phn 7, chng ta s tip tc hc cch to mt tiu
cho cc hng trong bng v to mt ct ng bng.

Trong phn ny chng ta s hc cch to tiu cho cc hng trong mt bng v to ct ng bng.
To tiu cho hng
Trong rt nhiu trng hp, mt bng ch cha cc tiu cho cc ct l cha bi v s c lc chng
ta cn mun to tiu cho cc hng trong bng na. lm iu ny th cng kh l d dng bi v
JScrollPane khng ch c viewport cho tiu ca ct m cn c cho tiu ca hng na. Khng ging
nh viewport cho tiu ca ct, theo mc nh, viewport cho tiu ca hng l trng. Tuy nhin, nh
ni trn, vic to ra mt tiu cho hng v hin th n l kh d dng.
Di y chng ta to mt lp RowNumberHeader trong file RowNumberHeader.java lm mt tiu
cho hng trong bng v d ca chng ta. Bn cht ca tiu di y chnh l mt JTable, v model
cho JTable ny chnh l lp RowNumberHeaderModel. S ct ca bng ny l 1, s hng bng vi s
hng ca bng m ta ang mun thm tiu cho hng. Gi tr trong tng ca bng bng vi gi tr
ca ch s hng tng ng cng thm mt n v.

public class RowNumberHeader extends JTable{
protected JTable mainTable;

public RowNumberHeader (JTable table){
super();
mainTable = table;
setModel(new RowNumberTableModel());
setPreferredScrollableViewportSize(getMinimumSize());
setRowSelectionAllowed(false);
JComponent renderer = (JComponent)getDefaultRenderer(Object.class);
LookAndFeel.installColorsAndFont(renderer, "TableHeader.background",
"TableHeader.foreground",
"TableHeader.font");
LookAndFeel.installBorder(this, "TableHeader.cellBorder");
}

@Override
public int getRowHeight(int row){
return mainTable.getRowHeight();
}

class RowNumberTableModel extends AbstractTableModel{

public int getRowCount() {
return mainTable.getModel().getRowCount();
}

public int getColumnCount() {
return 1;
}

public Object getValueAt(int rowIndex, int columnIndex) {
return new Integer(rowIndex+1);
}
}
}

Gi chng ta thay i lp SimpleTableTest nh sau:

public class SimpleTableTest extends JFrame{
protected JTable table;

public SimpleTableTest(){
[...]
JScrollPane jsp = new JScrollPane(table);
JViewport jvp = new JViewport();
jvp.setView(new RowNumberHeader(table));
jsp.setRowHeader(jvp);
pane.add(jsp, BorderLayout.CENTER);
addHeaderListener();
[...]
}

public void addHeaderListener(){
[...]
}

public static void main(String [] args){
[...]
}
}

By gi chy chng trnh, ta s tiu ca hng hin ln l s th t ca cc hng nh hnh di y:

To ct ng bng
Ngoi vic hin th tiu cho hng, s c lc chng ta cn mun ng bng mt hay nhiu ct trong
mt bng li sao cho chng vn nguyn v tr k c khi chng ta cun thanh cun ngang trong bng.
Trong v d ca chng ta, chng ta c th ng bng ct u tin (ct First Name) sao cho n lun lun
c th nhn thy khi m chng ta cun thanh trt ngang ca bng. Cc bc lm ct ng bng s
nh sau:
1. To mt JTable v chng ta gi n l bng chnh. Dng mt JScrollPane bc JTable ny li. Bng
chnh ny c nhim v hin th nhng d liu khng b ng bng.
2. To mt JTable th hai, chng ta gi n l bng tiu v cng thm n vo JScollPane. Bng ny s s
dng TableModel ging ca bng chnh nhng s hin th cc ct b ng bng
3. To mt TableColumnModel sau ny s gn n vo bng tiu
4. Xa cc i tng ca TableColum tng ng vi cc ct b ng bng trong TableColumModel ca bng
chnh, v sau thm chng vo TableColumModel ca bng tiu m chng ta to bc 3
5. Gn TableColumModel chng ta to bc 3 vo bng tiu s dng phng thc setColumnModel()
6. JScrollPane cha bng tiu by gi cng cha mt JTableHeader ca bng tiu trong column
header viewport ca n. Ly mt tham chiu n JTableHeader ny, v chuyn n n gc trn bn tri ca
JScrollPane ci c cha bng chnh. Chng ta c th lm iu ny s dng phng thc setCorner() ca
JScrollPane c cha bng chnh.
7. t rng a thch cho viewport ca bng tiu sao cho n ch rng hin th cc ct b ng bng.
rng mc nh ca n l 450, v rng ny lun ln hn rng cn thit.
Tm li, ng bng cc ct trong mt bng, chng ta chia bng ra thnh hai bng con. Mt bng
chnh hin th cc ct khng ng bng. Bng tiu cn li hin th cc ct ng bng v ng
vai tr nh mt tiu cho hng trong ca s cun c cha bng chnh. Tiu ct ca bng tiu
ny c chuyn n gc trn bn tri ca ca s cun c cha bng chnh. Chng ta to mt lp
lFrozenColumnHeader trong file FrozenColumnHeader.java nh sau:

public class FrozenColumnHeader extends JScrollPane{
protected JTable mainTable;
protected JTable headerTable;
protected int columnCount;

public FrozenColumnHeader(JTable table, int columns){
super();
mainTable = table;
headerTable = new JTable(mainTable.getModel());
getViewport().setView(headerTable);
columnCount = columns;
}

@Override
public void addNotify(){
TableColumn column;
super.addNotify();
TableColumnModel mainModel = mainTable.getColumnModel();
TableColumnModel headerModel = new DefaultTableColumnModel();
int frozenWidth = 0;
for(int i = 0; i<columnCount; i++){
column = mainModel.getColumn(0);
mainModel.removeColumn(column);
headerModel.addColumn(column);
frozenWidth += column.getPreferredWidth() +
headerModel.getColumnMargin();
}

headerTable.setColumnModel(headerModel);
Component columnHeader = getColumnHeader().getView();
getColumnHeader().setView(null);
JScrollPane mainScrollPane =
(JScrollPane)SwingUtilities.getAncestorOfClass(JScrollPane.class,
mainTable);
mainScrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, columnHeader);
headerTable.setPreferredScrollableViewportSize(new Dimension(frozenWidth,
0));
}
}

Chng ta c th s dng lp va to trn bng cch to mt i tng ca n v truyn vo contructor
ca n mt tham chiu n ci JTable l bng chnh ca chng ta, ng thi mt tham s l s lng ct
s b ng bng (tnh t ct u tin trong bng chnh). Trong v d, ta c th sa lp SimpleTableTest
thnh nh sau:

public class SimpleTableTest extends JFrame{
protected JTable table;

public SimpleTableTest(){
[...]
JScrollPane jsp = new JScrollPane(table);
JViewport jvp = new JViewport();
jvp.setView(new FrozenColumnHeader(table, 1));
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
jsp.setRowHeader(jvp);
pane.add(jsp, BorderLayout.CENTER);
addHeaderListener();

[...]
}

public void addHeaderListener(){
[...]
}

public static void main(String [] args){
[...]
}
}

By gi chy chng trnh chng ta s thy rng khi chng ta cun thanh trt ngang th ct First Name
b ng bng s vn gi nguyn v tr ca n nh hnh di y:

Mc d v d trn ch minh ha lm th no ng bng mt ct, nhng chng ta hon ton c th s
dng k thut trn ng bng nhiu ct. Vi cc tip cn , chng ta cng c th ng bng cc
dng d liu trong mt bng bng cch to ra mt bng c cha cc dng cn ng bng ri thm n
vo column header viewport ca JScrollPane.
Trong phn 8, chng ta s tm hiu cch sp xp cc dng trong mt bng theo chiu tng dn hoc
gim dn ca cc gi tr trong mt ct no ca bng.
Trong phn ny, chng ta s tm hiu cch sp xp cc hng trong mt bng theo chiu tng dn
hoc gim dn ca cc gi tr trong mt ct no ca bng.
Sp xp cc hng trong mt bng
Khi hin th thng tin trong mt JTable, s c lc chng ta mun sp xp li cc hng trong bng theo
chiu tng dn hoc gim dn ca cc gi tr trong mt hoc nhiu ct ca bng. Bi v vic sp xp
thng l chm v s tr thnh phc tp khi m tp d liu ca chng ta ln, v vy chng ta nn c cc
d liu c sp xp sn t mt ng dng bn ngoi. V d nh nu chng ta hin th d liu ly t
mt c s d liu quan h, chng ta c th ly c tp d liu c sp xp sn t cu truy vn.
Tuy nhin, s c i khi v mt l do no chng ta cn phi sp xp d liu trn chnh ci bng ca
chng ta, v bi v JTable khng trc tip h tr vic sp xp ny, cho nn chng ta phi t tay vit
nhng dng lnh thc hin vic ny.
sp xp d liu hin th trong mt bng, chng ta c th s dng mt trong hai cch tip cn: Cch
th nht l sp xp d liu ngay ti ch, cch th hai l vic sp xp c thc hin thng qua mt lp
nm gia JTable v TableModel. Sp xp d liu ngay ti ch c ngha l chng ta thay i v tr ca d
liu trong mt mng hoc trong mt i tng collection. V d nh trong trng hp ca chng ta, d
liu c nh ngha trong lp TableValues, chng ta s sp xp li cc gi tr ny trong mng sao cho
chng tng dn hoc gim dn. Tc l trong cch tip cn ny, ta sp xp li d liu trong ci model ca
bng.
Mt cch tip cn c v linh ng hn l thm mt lp lm vic sp xp gia bng v ci model ca
n. C th hn, n lin quan n vic to ra mt TableModel th hai gi l model sp xp (sort model).
Model sp xp ny s c mt tham chiu n ci model gc (source model trong v d chnh l
TableValues) ca chng ta. Trong trng hp ny, d liu trong model gc khng cn phi chuyn i
hay thay i g. Thay vo , model sp xp c th to mt danh sch cc ch s. Cc ch s ny tham
chiu n cc d liu trong model gc v c sp xp theo th t tng dn hoc gim dn. Cho v d,
gi s c ba gi tr kiu String c lu trong model gc nh sau:
Kirk
Ashworth
Spyres
Model sp xp c th sp xp cc gi tr ny v to mt tp cc ch s tham chiu n chng. Trong
trng hp ny, cc ch s s c nh nh sau:
1
0
2
Bng vic s dng mt danh sch cc ch s tham chiu n cc hng trong model gc, d liu c
th xut hin theo th t sp xp, k c d trong thc t, d liu vn c lu theo th t ban u
ca n. Chng ta to mt lp l SortedTableModel trong file SortedTableModel.java nh sau:

public class SortedTableModel extends AbstractTableModel{

protected TableModel sourceModel;
protected int[] indexValues;

public SortedTableModel(TableModel model){
super();
sourceModel = model;
}

public int getRowCount() {
return sourceModel.getRowCount();
}

public int getColumnCount() {
return sourceModel.getColumnCount();
}

public Object getValueAt(int rowIndex, int columnIndex) {
if(indexValues != null){
rowIndex = getSourceIndex(rowIndex);
}
return sourceModel.getValueAt(rowIndex, columnIndex);
}

@Override
public void setValueAt(Object value, int row, int column){
if(indexValues != null){
row = getSourceIndex(row);
}
}

@Override
public boolean isCellEditable(int row, int column){
return sourceModel.isCellEditable(row, column);
}

@Override
public String getColumnName(int column){
return sourceModel.getColumnName(column);
}

@Override
public Class getColumnClass(int column){
return sourceModel.getColumnClass(column);
}

public int getSourceIndex(int index){
if(indexValues != null){
return indexValues[index];
}
return -1;
}

public void sortRows(int column, boolean ascending){
SortedItemHolder holder;
TreeSet sortedList = new TreeSet();
int count = getRowCount();
for(int i =0; i< count; i++){
holder = new SortedItemHolder(sourceModel.getValueAt(i, column),i);
sortedList.add(holder);
}
indexValues = new int[count];
Iterator iterator = sortedList.iterator();
int index = (ascending ?0: count-1);
while(iterator.hasNext()){
holder = (SortedItemHolder)(iterator.next());
indexValues[index] = holder.position;
index += (ascending ? 1: -1);
}
refreshViews();
}

public void clearSort(){
indexValues = null;
refreshViews();
}

public void refreshViews(){
fireTableDataChanged();
}

class SortedItemHolder implements Comparable{

public final Object value;
public final int position;

public SortedItemHolder(Object value, int position){
this.value = value;
this.position = position;
}

public int compareTo(Object parm) {
SortedItemHolder holder = (SortedItemHolder)parm;
Comparable comp = (Comparable)value;
int result = comp.compareTo(holder.value);
if(result == 0){
result = (position < holder.position) ? -1: 1;
}
return result;
}

@Override
public int hashCode(){
return position;
}

@Override
public boolean equals(Object comp){
if(comp instanceof SortedItemHolder){
SortedItemHolder other = (SortedItemHolder)comp;
if((position == other.position) && (value == other.value)){
return true;
}
}
return false;
}
}
}

Phng thc sortRows c s dng ch ra d liu s c sp xp theo ct no v theo th t l
tng dn hay gim dn. Lp SortedItemHolder nm bn trong lp SortedTableModel lm nhim v sp
xp cc gi tr v tt nhin, bn trong lp SortedTableModel phi c mt tham chiu n model gc.
Thm vo , mt phn ca hai phng thc getValueAt() v setValueAt() l thc hin vic chuyn i
ch s hng gia hai model.
Bng vic s dng lp ny, chng ta c th hin th d liu trong bng theo mt th t c sp xp.
Chng hn sa on m trong lp SimpleTableTest sau s sp xp d liu trong bng theo gi tr tng
dn (t trn xung di) ca ct Account Balance:

public class SimpleTableTest extends JFrame{
protected JTable table;

public SimpleTableTest(){
Container pane = getContentPane();
pane.setLayout(new BorderLayout());
TableValues tv = new TableValues();
SortedTableModel stm = new SortedTableModel(tv);
stm.sortRows(TableValues.ACCOUNT_BALANCE, true);
table = new JTable(stm);
table.setRowSelectionAllowed(false);
[...]
JScrollPane jsp = new JScrollPane(table);
pane.add(jsp, BorderLayout.CENTER);
addHeaderListener();
[...]
}

public void addHeaderListener(){
[...]
}

public static void main(String [] args){
[...]
}
}

Kt qu khi chy chng trnh, cc hng trong bng s c sp xp li sao cho gi tr trong ct Account
Balance tng dn nh hnh di y:

Trong v d trn, mt ct c chn sp xp s c c nh trong on m v chng ta khng th
thay i khi m chng trnh chy. Tuy nhin, vic to mt giao din cho php ngi s dng
chn mt ct sp xp theo th cng kh d dng. Chng ta c th to mt renderer cho cc tiu
ca cc ct trong bng. Renderer ny s pht hin hin tng nhp chut, xc nh ct no ang c
con tr chut ch ti v sp xp cc d liu trong bng da trn cc gi tr ca ct . Chng ta to
lp SortedColumnHeaderRenderer trong file SortedColumnHeaderRenderer nh sau:

public class SortedColumnHeaderRenderer implements TableCellRenderer{
protected TableCellRenderer textRenderer;
protected SortedTableModel sortedModel;
protected int sortColumn = -1;
protected boolean sortAscending = true;

public SortedColumnHeaderRenderer(SortedTableModel model, TableCellRenderer
renderer){
sortedModel = model;
textRenderer = renderer;
}

public SortedColumnHeaderRenderer(SortedTableModel model){
this(model, null);
}

public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Component text;
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());

if(textRenderer != null){
text = textRenderer.getTableCellRendererComponent(table, value,
isSelected,
hasFocus, row,
column);
}else{
text = new JLabel((String)value, JLabel.CENTER);
LookAndFeel.installColorsAndFont((JComponent)text,
"TableHeader.background",
"TableHeader.foreground",
"TableHeader.font");
}
panel.add(text,BorderLayout.CENTER);

if(column == sortColumn){
BasicArrowButton bab = new
BasicArrowButton((sortAscending?SwingConstants.NORTH:SwingConstants.SOUTH));
panel.add(bab,BorderLayout.WEST);
}
LookAndFeel.installBorder(panel, "TableHeader.cellBorder");
return panel;
}

public void columnSelected(int column){
if(column!=sortColumn){
sortColumn = column;
sortAscending = true;
}else{
sortAscending = !sortAscending;
if(sortAscending) sortColumn = -1;
}
if(sortColumn != -1){
sortedModel.sortRows(sortColumn, sortAscending);
}else{
sortedModel.clearSort();
}
}
}

Chng ta cn ch n hai im quan trng trong renderer ny. Th nht, n c th c truyn vo
mt tham chiu n renderer khc. Renderer khc ny c nhim v l v on ch cho tiu . iu ny
cho php chng ta kt hp c cc chc nng ca nhiu renderer li vi nhau. Ni cch khc, chng ta
va c th to mt bng vi cc tiu c th hin th on ch trn nhiu dng, va cho php chng ta
chn ct sp xp mt cch ng bng cch nhp chut vo tiu ca ct .
Th hai, lp ny duy tr mt bin nhn din ra ct no s c sp xp. Bi v th, chng ta ch c
th s dng mt i tng duy nht ca lp renderer ny cho tt c cc ct m chng ta mun chn
sp xp trong bng.
Khi chng ta gn renderer ny n cc tiu , n cho php chng ta c th sp xp d liu theo gi tr
trong mt ct bng cch nhp chut vo tiu ca ct . Ln u tin chng ta kch vo tiu ca
mt ct, cc hng trong bng s c sp xp theo th t tng dn ca gi tr trong ct . Nu chng
ta kch chut mt ln na vo tiu , cc hng s c sp xp li nhng ln ny l theo th t
gim dn v ln kch chut th ba s l nguyn nhn cc hng c tr v v tr ban u khi cha
c sp xp. Khi m gi tr trong bng c sp xp, s c mt hin th xut hin ch th gi tr ny
c sp xp nh th no. l hnh mt mi tn hng ln trong trng hp sp xp cc gi tr theo
th th tng dn v hnh mt mi tn hng xung trong trng hp sp xp cc gi tr theo th t gim
dn (t trn xung di). Chng ta thay i lp SimpleTableTest nh sau:

public class SimpleTableTest extends JFrame{
protected JTable table;
protected SortedColumnHeaderRenderer renderer;

public SimpleTableTest(){
Container pane = getContentPane();
pane.setLayout(new BorderLayout());
TableValues tv = new TableValues();
SortedTableModel stm = new SortedTableModel(tv);
table = new JTable(stm);
table.setRowSelectionAllowed(false);
table.setColumnSelectionAllowed(true);
TableColumnModel tcm = table.getColumnModel();
TableColumn tc = tcm.getColumn(TableValues.GENDER);
tc.setCellRenderer(new GenderRenderer());
tc.setCellEditor(new GenderEditor());
MultiLineHeaderRenderer mlhr = new MultiLineHeaderRenderer();
renderer = new SortedColumnHeaderRenderer(stm, mlhr);
int count = tcm.getColumnCount();
for(int i=0;i<count; i++){
tc = tcm.getColumn(i);
tc.setHeaderRenderer(renderer);
}
JTableHeaderToolTips jthtt = new
JTableHeaderToolTips(table.getColumnModel());
[...]
addHeaderListener();

[...]
}

public void addHeaderListener(){
table.getTableHeader().addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent event){
JTableHeader header = (JTableHeader)(event.getSource());
int index = header.columnAtPoint(event.getPoint());
renderer.columnSelected(index);
table.setColumnSelectionInterval(index, index);
}
});
}

public static void main(String [] args){
[...]
}
}

Sau khi chy chng trnh v nhp chut ln ct Date of Birth, ta s thy cc gi tr trong ct ny c
sp xp li ging nh hnh di y:

S dng interface Comparable
Mt trong nhng gii hn ca cch sp xp m chng ta trnh by trn l vic s dng
interfaceComparable xc nh mi tng quan gia gi tr ca hai i tng (ln hn, nh hn, bng
nhau). Thng thng th trong Java 2, hu ht cc lp u ci t interface Comparable v iu cho
php chng ta c th sp xp cc i tng ca chng theo mt cch thc no . Cho v d nh cc
lp Integer, Float, Long, String, Date u ci t interface Comparable. Tuy nhin, lp Boolean th khng
ci t interface Comparable
(1)
, bi v mc d tt nhin l gi tr true khng bng vi gi tr false, nhng s
rt mp m trong vic quy nh gia true v false th gi tr no ln hn. Trong v d ca chng ta, nu
chng ta nhp chut vo tiu ca ct Gender, chng trnh s sinh ra mtClassCastException. y l
bi v chng ta ang c p cc gi tr thuc kiu Boolean v cc gi tr kiu Comparable.
Mt trong nhng cch gii quyt vn trn l chng ta s kim tra kiu d liu trong ct c
chn trc khi cc d liu trong ct c sp xp. Vic ly kiu d liu ca mt ct s c thc
hin bi phng thc getColumnClass() ca TableModel v chng ta c th s dng i tng tr v
thuc kiu Class ca phng thc xc nh xem lp ca n c ci t interface Comparable hay
khng. Tr li v d, chng ta thc hin vic ny bng vic thay i lp SimpleTableTest nh sau:

public class SimpleTableTest extends JFrame{
protected JTable table;
protected SortedColumnHeaderRenderer renderer;

public SimpleTableTest(){
[...]
}

public void addHeaderListener(){
table.getTableHeader().addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent event){
JTableHeader header = (JTableHeader)(event.getSource());
int index = header.columnAtPoint(event.getPoint());
Class dataType = table.getModel().getColumnClass(index);
Class[] interfaces = dataType.getInterfaces();
for(int i = 0; i<interfaces.length; i++){
if(interfaces[i].equals(java.lang.Comparable.class)){
renderer.columnSelected(index);
break;
}
}
table.setColumnSelectionInterval(index, index);
}
});

}

public static void main(String [] args){
[...]
}
}

Khi chy chng trnh, vi vic sa i nh trn gi y chng ta khng th chn sp xp theo gi tr
trong ct Gender nh hnh di y:

Tuy nhin, vn cn mt vn na sinh ra t vic lm ny l khi ta chn cc ct nh First Name hoc
Last Name, cc gi tr cng khng c sp xp. y l bi v trong TableModel chng ta ch ch nh
kiu d liu cho hai ct l Date of Birth v Account Balance. Cc ct khc s c ngm hiu rng
chng c kiu d liu l Object. Hay ni cch khc, chng trnh s khng thc hin sp xp trn cc
ct First Name, Last Name, Gender bi v chng trnh ang hiu cc ct ny c kiu d liu l Object,
m kiu Object th li khng ci t interface Comparable. Tuy nhin, vn ny c th gii quyt mt
cch d dng bng cch chng ta sa li phng thc getColumnClass() trong lp TableValues nh
sau:

public class TableValues extends AbstractTableModel{

public final static int FIRST_NAME = 0;
public final static int LAST_NAME = 1;
public final static int DATE_OF_BIRTH = 2;
public final static int ACCOUNT_BALANCE = 3;
public final static int GENDER = 4;

public final static boolean GENDER_MALE = true;
public final static boolean GENDER_FEMALE = false;
public final static String[] columnNames = {
"First Name", "Last Name", "Date of Birth", "Account\nBalance","Gender"
};

public Object[][] values = {
[...]
};

public int getRowCount() {
return values.length;
}

public int getColumnCount() {
return values[0].length;
}

public Object getValueAt(int rowIndex, int columnIndex) {
return values[rowIndex][columnIndex];
}

@Override
public String getColumnName(int column){
return columnNames[column];
}

@Override
public Class getColumnClass(int column){
Class dataType = super.getColumnClass(column);
if(column == ACCOUNT_BALANCE){
dataType = Float.class;
}else if(column == DATE_OF_BIRTH){
dataType = java.util.Date.class;
}else if((column == FIRST_NAME) || (column == LAST_NAME)){
dataType = String. class;
}else if(column == GENDER){
dataType = Boolean.class;
}
return dataType;
}

@Override
public boolean isCellEditable(int row, int column){
if(column == GENDER){
return true;
}
return false;
}

@Override
public void setValueAt(Object value, int row, int column){
values[row][column] = value;
}
}

By gi chy chng trnh, chng ta c th sp xp d liu trong bng da vo cc gi tr ca ct First
Name nh hnh di y:

Ch
(1): iu ny c l ch ng trong phin bn java c m tc gi dng vit v d minh ha. Theo mnh c bit
bt u t JDK 1.5, lp Boolean ca chng ta ci t interface Comparable v bng chng l khi chy chng
trnh ca chng ta, ct Gender vn c sp xp bnh thng nh hnh di y:


Cc bn cng c th tham kho thm ti y.
Nh vy sau bi vit ny chng ta nm c cch sp xp cc hng trong mt bng theo chiu
tng dn hoc gim dn ca cc gi tr trong mt ct no . Phn 9 s trnh by cch thm v xa mt
dng trong bng.

Trong phn ny chng ta s tm hiu v cch thm v xa d liu trong mt bng. thay i d liu
trong bng, chng ta cn thay i TableModel v sau thng bo cho listener ca n (hay ni cch
khc chnh l JTable) rng d liu b thay i.
on m di y l v d minh ha cho mt bng c 1 ct. C mt ch cho php chng ta thm
nhng dng mi vo trong bng.

public class RowAdder extends JFrame{
protected SimpleModel tableData;
protected JTable table;
protected JTextField textField;

public static void main(String[] args) {
RowAdder ra = new RowAdder();
ra.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ra.setSize(400, 300);
ra.setVisible(true);
}

public RowAdder(){
Container pane = getContentPane();
pane.setLayout(new BorderLayout());
tableData = new SimpleModel();
table = new JTable(tableData);
table.getColumnModel().getColumn(0).setPreferredWidth(300);
JScrollPane jsp = new JScrollPane(table);
pane.add(jsp, BorderLayout.CENTER);
textField = new JTextField();
textField.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event) {
addLineToTable();
}
});
pane.add(textField, BorderLayout.SOUTH);
}

protected void addLineToTable(){
tableData.addText(textField.getText());
textField.setText("");
}

class SimpleModel extends AbstractTableModel{
protected Vector textData = new Vector();

public void addText(String text){
textData.addElement(text);
fireTableDataChanged();
}

public int getRowCount(){
return textData.size();
}

public int getColumnCount(){
return 1;
}

public Object getValueAt(int row, int column){
return textData.elementAt(row);
}
}
}

Khi chy chng trnh, chng ta nhp ch vo trong ch sau nhn Enter. Mt dng mi trong s
c thm vo JTable nh hnh di y:

Khi nhn phm Enter vo ch, mt s kin s c sinh ra v x l s kin s gi phng
thcfireTableDataChanged() cp nht li d liu trong bng. Tuy nhin phng thc ny ch c ci
t trc trong lp AbstractTableModel, cn nu ci model m khng phi k tha t lp
AbstractTableModel th chng ta s khng c phng thc ny dng. Lc s phi t to ra mt
phng thc trong model ging nh l phng thc fireTableDataChanged() ca lp
AbstractTableModel. V d di y minh ha trong trng hp model ca chng ta ci t interface
TableModel th s lm nh sau:

public class RowAdder extends JFrame{
protected SimpleModel tableData;
protected JTable table;
protected JTextField textField;

public static void main(String[] args) {
RowAdder ra = new RowAdder();
ra.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ra.setSize(400, 300);
ra.setVisible(true);
}

public RowAdder(){
Container pane = getContentPane();
pane.setLayout(new BorderLayout());
tableData = new SimpleModel();
table = new JTable(tableData);
table.getColumnModel().getColumn(0).setPreferredWidth(300);
JScrollPane jsp = new JScrollPane(table);
pane.add(jsp, BorderLayout.CENTER);
textField = new JTextField();
textField.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event) {
addLineToTable();
}
});
pane.add(textField, BorderLayout.SOUTH);
}

protected void addLineToTable(){
tableData.addText(textField.getText());
textField.setText("");
}

class SimpleModel implements TableModel{
protected Vector textData = new Vector();
protected EventListenerList listenerList = new EventListenerList();

public void addText(String text){
textData.addElement(text);
notifyListenersOfDataChange();

}

public void notifyListenersOfDataChange(){
TableModelEvent event= new TableModelEvent(this);
Object[] listeners = listenerList.getListenerList();
for(int i = 0; i< listeners.length; i++){
if(listeners[i] == TableModelListener.class){
TableModelListener listener = (TableModelListener) (listeners[i+1]);
listener.tableChanged(event);
}
}
}

public int getRowCount(){
return textData.size();
}

public int getColumnCount(){
return 1;
}

public Object getValueAt(int row, int column){
return textData.elementAt(row);
}

public String getColumnName(int columnIndex) {
return "A";
}

public Class getColumnClass(int columnIndex) {
return String.class;
}

public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}

public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
textData.setElementAt(aValue, rowIndex);
}

public void addTableModelListener(TableModelListener l) {
listenerList.add(TableModelListener.class, l);
}

public void removeTableModelListener(TableModelListener l) {
listenerList.remove(TableModelListener.class, l);
}
}
}

Trong on m trn, chng ta to ra phng thc notifyListenersOfDataChange() v phng thc ny
tng ng vi phng thc fireTableDataChanged() khi dng AbstractTableModel. Bn cht vn l
gi phng thc tableChanged() ca cc listener v truyn vo mt i tng caTableModelEvent.
Cc listener s c ng k vi mt model qua phng thcaddTableModelListener() ca model .
Listener trong trng hp ny chnh l ci JTable ang tham chiu n ci model SimpleModel.
Hin th mt dng trong bng
Trong v d bn trn, khi m chng ta nhp ch vo ch ri n phm Enter, mt dng mi s c
thm vo bng. Khi mt vi dng u c thm vo, chng ta s nhn thy chng ngay lp tc. Tuy
nhin, khi s dng nhiu vt qu kch thc th s dn n s xut hin ca thanh cun dc. V n
y, vn chnh l khng th nhn thy c dng va c thm vo bng tr khi chng ta phi cun
thanh cun xung di. Hnh di y minh ha cho vic khi m nhp qu 14 dng vo bng, nu khng
cun thanh cun xung di, th t dng 15 tr xung, chng ta s khng nhn thy c.

Nh vy, chng ta phi tm cch no cho thanh cun t cun xung khi m mt dng mi c
thm vo bng. C lm iu ny bng cch ly ra i tng JViewport ca ca s cun v sau t li
v tr cho n sao cho dng cui cng ca bng lun c hin ln trong ca s cun. Chng ta sa lp
RowAdder nh sau:

public class RowAdder extends JFrame{
protected SimpleModel tableData;
protected JTable table;
protected JTextField textField;

public static void main(String[] args) {
RowAdder ra = new RowAdder();
ra.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ra.setSize(400, 300);
ra.setVisible(true);
}

public RowAdder(){
Container pane = getContentPane();
pane.setLayout(new BorderLayout());
tableData = new SimpleModel();
table = new JTable(tableData);
table.getColumnModel().getColumn(0).setPreferredWidth(300);
table.addComponentListener(new TableScroller());
JScrollPane jsp = new JScrollPane(table);
pane.add(jsp, BorderLayout.CENTER);
textField = new JTextField();
textField.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event) {
addLineToTable();
}
});
pane.add(textField, BorderLayout.SOUTH);
}

protected void addLineToTable(){
tableData.addText(textField.getText());
textField.setText("");
}

class SimpleModel implements TableModel{
[...]
}

class TableScroller extends ComponentAdapter{
public void componentResized(ComponentEvent event){
int lastRow = tableData.getRowCount() -1;
int cellTop = table.getCellRect(lastRow, 0, true).y;
JScrollPane jsp = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, table);
JViewport jvp = jsp.getViewport();
int portHeight = jvp.getSize().height;
int position = cellTop - (portHeight - table.getRowHeight() - table.getRowMargin());
if(position >= 0){
jvp.setViewPosition(new Point(0, position));
}
}
}
}

Phng thc componentResized() ly v kch thc v ta ca mt dng trong bng bng vic gi
phng thc getCellRect(). Sau n s dng v tr thng ng ca dng, kch thc ca viewport, v
chiu cao ca dng iu chnh v tr nhn ca viewport sao cho chng ta c th lun nhn thy c
dng cui cng ca bng. Sau khi chy chng trnh, by gi chng ta thm dng n u, thanh cun
s t ng cun xung ti nh hnh di y:

Nh vy, trong phn ny chng ta bit cch thm mt dng mi vo bng nh th no. Thm vo
, chng ta cng bit cch hin th mt dng ti ng v tr m chng ta mong mun. Lot bi Cch
s dng JTable ca Swing trong java s dng y vi hi vng cung cp cho bn c nhng kin
thc c bn v cch s dng JTable mt thnh phn rt hay c s dng trong cc ng dng vit
bng java.
Ngun: Brett Spell Pro Java Programming, Second Edition

You might also like