Swing是java為桌面開(kāi)發(fā)而設(shè)計(jì)一個(gè)重要GUI工具包,整個(gè)設(shè)計(jì)是基于AWT技術(shù)上的擴(kuò)展。加上Java在網(wǎng)絡(luò)的優(yōu)勢(shì)和跨平臺(tái)的特點(diǎn),Swing已經(jīng)無(wú)處不在,在Java2D的性能加強(qiáng),可插入式的Look And Feel,主題(Theme)和JDK5.0"Tiger"的出現(xiàn)后,基于Swing的技術(shù)框架如雨后春筍誕生,像Infonode,JGoooodes都是很優(yōu)秀的框架。
很多用Swing開(kāi)發(fā)的人員在設(shè)計(jì)GUI程序的時(shí)候,都遇上代碼量大和代碼邏輯復(fù)雜的問(wèn)題,加上Swing的設(shè)計(jì)理論門(mén)檻相對(duì)比較高,令桌面程序的開(kāi)發(fā)在國(guó)內(nèi)不能流行,分析其技術(shù)原因如下:
1.Swing是MVC架構(gòu)的體系,一般和用戶(hù)界面相關(guān)的程序,必定觸發(fā)控制器(Controler),然后在模型(Model)層相應(yīng)處理,這是一般最普遍的處理,也可以說(shuō),因?yàn)镾wing的V和C聯(lián)系得太緊密,所以一般程序員處理數(shù)據(jù)和UI事件都以Model為入口。
2.Model要響應(yīng)事件,開(kāi)發(fā)人員就必須集成相應(yīng)UI控件的Model,并在捕捉事件的方法里寫(xiě)入相應(yīng)處理的代碼。
基于以上的原因和界面開(kāi)發(fā)的需求是千變?nèi)f化的,導(dǎo)致模型(Model)代碼量大,并且復(fù)用性低,可調(diào)試性低等問(wèn)題。所以在一些UI功能添加上,對(duì)一般的桌面程序員來(lái)說(shuō)可謂"百上加斤".到底我們能不能添加一些基本功能,又不影響二次開(kāi)發(fā)用戶(hù)的易擴(kuò)展性呢?
本文旨在從以上問(wèn)題出發(fā),利用自己的實(shí)際的工作經(jīng)驗(yàn),從本人的Swing2CN開(kāi)源項(xiàng)目中取出部分源代碼做例子,希望點(diǎn)燃更多的聰明的火花。
設(shè)計(jì)一個(gè)工具能讓所有用的開(kāi)發(fā)人員輕易擴(kuò)展其控件,甚至不用添加額外的代碼或者改變其設(shè)計(jì)的數(shù)據(jù)模式,是最完美的結(jié)果。到底怎么實(shí)現(xiàn)呢?答案是,接口。從標(biāo)準(zhǔn)的Swing控件的Model接口中的方法設(shè)計(jì)關(guān)于GUI交互的功能和改變,是不會(huì)影響二次開(kāi)發(fā)人員的原有設(shè)計(jì)模式和代碼。以下是我的設(shè)計(jì)思想。其中的圓圈O指的便是Model里面的接口方法。

現(xiàn)在就以這種思想去設(shè)計(jì)一個(gè)功能類(lèi),我們就以JTable實(shí)現(xiàn)列排序的功能為例子.首先,我們從TableModel知道JTable的Model基本的方法有:
addTableModelListener(TableModelListener l)getColumnClass(int columnIndex)getColumnCount()getColumnName(int columnIndex)getRowCount()getValueAt(int rowIndex, int columnIndex)isCellEditable(int rowIndex, int columnIndex)removeTableModelListener(TableModelListener l)setValueAt(Object aValue, int rowIndex, int columnIndex)
排序方法主要還是用到和數(shù)據(jù)相關(guān)的方法為主,并且涉及以下技術(shù)點(diǎn):
代碼運(yùn)行設(shè)計(jì):
讓UI觸發(fā)排序事件,然后通知工具類(lèi),工具類(lèi)通過(guò)Model接口方法處理完排序,然后再更新UI代表.這就算完成了一次排序事件.
工具類(lèi)結(jié)構(gòu)設(shè)計(jì):
SortManager類(lèi)構(gòu)造函數(shù)就把JTable的引用帶進(jìn)去,這樣,用戶(hù)只需要生成一個(gè)SortManager對(duì)應(yīng)一個(gè)JTable實(shí)例就可以添加排序功能.SortManager還提供兩個(gè)帶參數(shù)的構(gòu)造函數(shù),讓用戶(hù)能夠指定哪幾列或者哪一列需要排序功能.
我寫(xiě)了一個(gè)測(cè)試類(lèi)來(lái)顯示這個(gè)工具類(lèi)的效果,開(kāi)發(fā)人員只需要一行代碼就可以在無(wú)損害已經(jīng)有的JTable結(jié)構(gòu)下添加排序的功能,相當(dāng)便利,能減少開(kāi)發(fā)時(shí)間和代碼量.但這個(gè)工具在極端的情況下是不適宜使用,(譬如TableHeader被指定時(shí)).所以,無(wú)絕對(duì)的通用,只有相對(duì)的通用.
測(cè)試的代碼和效果如下:
package org.swing2cn.test;import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.table.*;import org.swing2cn.table.*;public class TestSortTable extends JPanel { public TestSortTable() { init(); } PRivate void init() { setLayout(new BorderLayout()); JTable table = new JTable(); Object[][] obj=new Object[][]{{"asdas","12321","3as3","eqw22"}, {"das2","asd","qweqw","as23"},{"aere","r32re","ewfse","werew3"}}; DefaultTableModel model=new DefaultTableModel(obj,new Object[]{"a","b","c","d"}); table.setModel(model); new KeyPlugin(table); JScrollPane scrPane = new JScrollPane(table); JButton addBTn = new JButton("新增行"); addBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { } }); JPanel btnPane = new JPanel(); btnPane.add(addBtn); add(scrPane); add("South", btnPane); } public static void main(String[] args) { JFrame frame = new JFrame("Test"); frame.setDefaultCloSEOperation(frame.EXIT_ON_CLOSE); frame.getContentPane().add(new TestSortTable()); frame.pack(); frame.setVisible(true); }} 新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注