1. 前言
??? JTable是Swing包中非常易用" title="易用">易用和功能強(qiáng)大的表格控件,,但是它仍然有許多缺點(diǎn),它不支持很多在實(shí)際的表格設(shè)計(jì)中很常用的特性,JTable不支持的特性如下:
1)?行列合并
2)?不同行有不同的高度
3)?行的行頭
4)?單元格的邊框
??? 因?yàn)镴Table有著這些限制,,所以往往不能夠滿足表格設(shè)計(jì)的需要,因此,,我們?cè)O(shè)計(jì)并且開發(fā)了XTable,,XTable能夠支持上述JTable無法支持的特性,而且XTable繼承了JTable的可編程" title="可編程">可編程的優(yōu)點(diǎn),。
XTable的設(shè)計(jì)
??? JTable的設(shè)計(jì)思想使它擁有良好的可編程性,。比如在單元格的顯示和編輯方面,JTable提供了render和editor的概念,。開發(fā)者通過繼承相應(yīng)的接口,,能夠?qū)崿F(xiàn)自己的renderer和editor。
??? XTable的設(shè)計(jì)參考了JTable的思想,,遵守了軟件工程的M-V-C的設(shè)計(jì)方法,,把數(shù)據(jù),顯示和控制分開,。在使用和可編程方面,,也盡量讓XTable和JTable幾乎沒有什么區(qū)別。
??? 基于上述的思想,,我們?cè)O(shè)計(jì)了XTable這個(gè)控件,,一個(gè)簡略但是能夠體現(xiàn)整個(gè)完整的XTable的結(jié)構(gòu)的UML圖如下:
??? 現(xiàn)在開始分析這個(gè)設(shè)計(jì)中的各個(gè)包的作用。
??? XTable.model是表示該XTable中的數(shù)據(jù)的包,,該包包含著表示數(shù)據(jù)的接口和缺省的實(shí)現(xiàn)類,。其中XTableModel是表格中的數(shù)據(jù)的接口,從這個(gè)接口,,XTable可以取得該表格中的每一格中包含的數(shù)據(jù),,該表格中的每一格合并的行列數(shù)和該單元格的邊框信息,除此之外,,還可以獲得該表格的每一行的高度和每一列的高度,。XTableColumnModel這個(gè)接口提供的是獲得列頭部信息的接口,比如列名,。XTableRowModel這個(gè)接口提供的是獲得行頭部的信息的接口,,比如行的名字。XTableSelectionModel提供的是獲得當(dāng)前被選中的塊信息的接口,。XTable.model包中還包含這幾個(gè)接口的缺省實(shí)現(xiàn)類,,開發(fā)者可以直接使用這些缺省實(shí)現(xiàn)的類。
??? XTable.Event是表示該XTable中事件的包,,該包中定義了XTable中的所有事件監(jiān)聽類和事件類,。XTable中所有的事件類都繼承自java.util.EventObject,。所有的事件監(jiān)聽類都繼承自EventListener。其中XTableModelListener監(jiān)聽的是XTableModel發(fā)生的變化,。XTableSelectionListener監(jiān)聽的是XTable選擇區(qū)域的變化,。CellEditorListener監(jiān)聽的是當(dāng)前正在編輯的單元格的事件。這三個(gè)Listener的實(shí)現(xiàn)者都是XTable,。XTableRowModelListener監(jiān)聽的是行頭的數(shù)據(jù)的變化,,比如某個(gè)行名發(fā)生了變化,XTableColumnModelListener監(jiān)聽的是列頭數(shù)據(jù)的變化,,比如某個(gè)列名發(fā)生了變化,。XTableRowModelListenr由XTableRowHeader實(shí)現(xiàn),XTableColumnModelListener由XTableColHeader實(shí)現(xiàn),。
????XTable.renderer定義了一個(gè)renderer必須實(shí)現(xiàn)的接口,。Renderer是XTable中顯示數(shù)據(jù)的方法,XTable中的單元格使用renderer來顯示該單元格中的數(shù)據(jù),。XTableCellRenderer是XTable中的renderer的接口,,DefaultXTableCellRenderer是該接口的缺省實(shí)現(xiàn)類,開發(fā)者可以直接使用,。XTableColumnHeaderRenderer是該列頭的renderer類,,而XTableRowHeaderRenderer是該行頭的renderer類。
??? XTable.header包含的是列頭和行頭,,XTableColHeader是列頭,,XTableRowHeader是行頭,其中列頭實(shí)現(xiàn)了XTableColumnModelListener,,行頭實(shí)現(xiàn)了XTableRowModelListener,。
XTable.editor包含的是單元格的editor需要實(shí)現(xiàn)的接口,其中XTableCellEditor就是該XTable中單元格需要實(shí)現(xiàn)的接口,,XTableCellEditor繼承自javax.swing.CellEditor,,其中為了方便開發(fā)者,提供了一個(gè)繼承自XTableCellEditor的虛類AbstractXTableCellEditor,。實(shí)現(xiàn)Editor的時(shí)候,繼承這個(gè)虛類比直接實(shí)現(xiàn)XTableCellEditor要方便很多,。同時(shí),,該包中還提供了一個(gè)缺省的DefaultXTableCellEditor供開發(fā)者使用。
??? XTable類就是這個(gè)XTable的中心類,,和JTable一樣,,一個(gè)XTable的實(shí)例代表了一個(gè)表格。XTable中包含一個(gè)XTableColHeader和XTableRowHeader的實(shí)例,,用于代表表格的列頭和行頭,。XTable同時(shí)還是XTableModelListener,,XTableSelectionListener和CellEditorListener的實(shí)現(xiàn)類,負(fù)責(zé)處理表格中的model,,selection和editor激發(fā)的事件,。
2 XTable的實(shí)現(xiàn)
??? XTable在設(shè)計(jì)方面遵守了MVC的思想,并且保持了和JTable一樣的可編程性質(zhì),。在實(shí)現(xiàn)方面,,XTable比JTable更加困難。因?yàn)橐獙?shí)現(xiàn)行合并和列合并,,所以JTable這樣的布局方式不再適用,,XTable使用了GridBagLayout來做整體布局。
??? 在事件的處理方面,,XTable捕獲了鼠標(biāo)事件,,并且解釋這些鼠標(biāo)事件,分發(fā)給不同的Listener,,比如正在選擇事件或者選擇結(jié)束事件,。
??? 在編輯方面,XTable將事件的處理權(quán)下放給Editor,,根據(jù)Editor返回的值是編輯結(jié)束還是取消編輯來動(dòng)態(tài)更新" title="動(dòng)態(tài)更新">動(dòng)態(tài)更新單元格里的信息,。
????完成的XTable是一個(gè)實(shí)用的開發(fā)包" title="開發(fā)包">開發(fā)包,目前已經(jīng)用于開發(fā)一些商業(yè)程序,。
3.?XTable的使用方法
一個(gè)簡單的例子如下:
import java.awt.*;
import javax.swing.*;
import java.util.Vector;
import model.DefaultXTableColumnModel;
import model.DefaultXTableRowModel;
import model.DefaultXTableModel;
import header.XTableColHeader;
import header.XTableRowHeader;
import datatype.*;
import table.XTable;
public class CellShower extends JFrame{
?? static int [] widths = { 64, 64, 100, 100};
?? static int [] heights = { 64, 64, 32 ,32 };
? public CellShower() {
?
?//初始化XTableModel,,往里面填要顯示的數(shù)據(jù)和行列和并信息
?? DefaultXTableModel model = new DefaultXTableModel(heights, widths);
?? ImageIcon icon = new ImageIcon("ft.gif");
?? model.setValueAt(icon,0, 0);
?? model.setValueAt(new ColorType(Color.red), 3,3);
?? model.setValueAt(new Length(2,"cm"), 3, 3);
?? model.setCellRowSpan(0, 0, 2);
?? model.setDownBorderAt(2,3,1);
?? model.setValueAt(new StringType("lby\nsafa"),0,2);
?? model.setValueAt(new StringType("School"),1,1);
?? model.setValueAt(new IntType(100000), 3,4);
?? model.setValueAt(new BooleanType(true), 3,5);
?? model.setValueAt(new DoubleType(1.345325), 2, 4);
?? model.setCellColSpan(1,1,2);
?? model.setCellRowSpan(1,1,2);
?? model.setRangeBorder(1,1,2,3);
??
? //將該XTableModel賦給某個(gè)XTable的實(shí)例
? XTable table = new XTable(model);
? getContentPane().add(table,BorderLayout.CENTER);
?
? //設(shè)定該XTable的窗體容器
? table.setFrame(this);
? setSize(500,400);
? setVisible(true);
}
? public static void main(String args[])
? {
??? CellShower cell = new CellShower();
? }
}
運(yùn)行這個(gè)例子,得到的表格如下:
??? XTable還有更為復(fù)雜的使用方法,,比如實(shí)現(xiàn)一個(gè)自己的renderer或者Editor等,,XTable良好的可編程特性給程序員提供了很多可擴(kuò)展的功能。
4. 總結(jié)
??? 在企業(yè)內(nèi)部,,很多數(shù)據(jù)都以表格的方式給出,,而JTable在表格的表現(xiàn)方面有著很多的缺陷,因此我們?cè)O(shè)計(jì)并實(shí)現(xiàn)了這個(gè)比JTable更為強(qiáng)大的XTable,,在整個(gè)設(shè)計(jì)中遵守了MVC的設(shè)計(jì)模式并且參考了JTable,,使得XTable像JTable一樣易用而且可編程。最后實(shí)現(xiàn)完畢的XTable就是這樣一個(gè)功能強(qiáng)大,,簡單易用而且可編程的" title="可編程的">可編程的購件,,已經(jīng)應(yīng)用于商業(yè)程序的開發(fā)中。
?