Swing是java為桌面開發而設計一個重要GUI工具包,整個設計是基于AWT技術上的擴展。加上Java在網絡的優勢和跨平臺的特點,Swing已經無處不在,在Java2D的性能加強,可插入式的Look And Feel,主題(Theme)和JDK5.0"Tiger"的出現后,基于Swing的技術框架如雨后春筍誕生,像Infonode,JGoooodes都是很優秀的框架。
很多用Swing開發的人員在設計GUI程序的時候,都遇上代碼量大和代碼邏輯復雜的問題,加上Swing的設計理論門檻相對比較高,令桌面程序的開發在國內不能流行,分析其技術原因如下:
1.Swing是MVC架構的體系,一般和用戶界面相關的程序,必定觸發控制器(Controler),然后在模型(Model)層相應處理,這是一般最普遍的處理,也可以說,因為Swing的V和C聯系得太緊密,所以一般程序員處理數據和UI事件都以Model為入口。
2.Model要響應事件,開發人員就必須集成相應UI控件的Model,并在捕捉事件的方法里寫入相應處理的代碼。
基于以上的原因和界面開發的需求是千變萬化的,導致模型(Model)代碼量大,并且復用性低,可調試性低等問題。所以在一些UI功能添加上,對一般的桌面程序員來說可謂"百上加斤".到底我們能不能添加一些基本功能,又不影響二次開發用戶的易擴展性呢?
本文旨在從以上問題出發,利用自己的實際的工作經驗,從本人的Swing2CN開源項目中取出部分源代碼做例子,希望點燃更多的聰明的火花。
設計一個工具能讓所有用的開發人員輕易擴展其控件,甚至不用添加額外的代碼或者改變其設計的數據模式,是最完美的結果。到底怎么實現呢?答案是,接口。從標準的Swing控件的Model接口中的方法設計關于GUI交互的功能和改變,是不會影響二次開發人員的原有設計模式和代碼。以下是我的設計思想。其中的圓圈O指的便是Model里面的接口方法。
現在就以這種思想去設計一個功能類,我們就以JTable實現列排序的功能為例子.首先,我們從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)
排序方法主要還是用到和數據相關的方法為主,并且涉及以下技術點:
代碼運行設計:
讓UI觸發排序事件,然后通知工具類,工具類通過Model接口方法處理完排序,然后再更新UI代表.這就算完成了一次排序事件.
工具類結構設計:
SortManager類構造函數就把JTable的引用帶進去,這樣,用戶只需要生成一個SortManager對應一個JTable實例就可以添加排序功能.SortManager還提供兩個帶參數的構造函數,讓用戶能夠指定哪幾列或者哪一列需要排序功能.
我寫了一個測試類來顯示這個工具類的效果,開發人員只需要一行代碼就可以在無損害已經有的JTable結構下添加排序的功能,相當便利,能減少開發時間和代碼量.但這個工具在極端的情況下是不適宜使用,(譬如TableHeader被指定時).所以,無絕對的通用,只有相對的通用.
測試的代碼和效果如下:
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); }}
新聞熱點
疑難解答