轉載:http://blog.csdn.net/chosen0ne/article/details/4453267
Swing組件根據其所操作的數據類型分為兩種,一種是標量數據類型的組件,一類是復合數據類型的組件。標量數據類型的組件操作的是基本類型的數據,如字符串、布爾、數字等,此類型組件包括JTextField、JCheckBox、JLabel、JButton等。復合數據類型的組件操作的是諸如向量、矩陣和非線形等類型的數據。向量數據類型的組件有JComboBox、JList,矩陣數據類型的組件有JTable,非線形數據類型的組件如 JTree。
為更形象地展現各種類型的數據,復合數據類型的組件往往采用標量數據類型組件來表現每種數據元素。比如JTable的某一列數據是字符串類型,那么該列的單元格往往用JLabel方式展現每個字符串;如果一列數據是布爾類型,那么該列的單元格往往用JCheckBox方式展現每個布爾值。
如何實現復合數據類型的組件的渲染呢?最直接的是在paint方法中一個一個地根據數據類型畫出每一個組件,但這種方法很顯然代碼復用率很低,大量重復了相應標量型組件的代碼,代碼的維護和同步會非常困難,也不容易實現皮膚切換。
為解決此問題,Swing體系中提出了所謂渲染器(Renderer)的概念,其核心思想是使用接口,封裝和復用已有標量型組件的渲染代碼,降低代碼重復率,提高組件的可擴展性。
JTable負責管理表格的可視外觀,在繪制每個單元格時,調用getCellRenderer(int row,int col)獲得當前單元格的渲染器,即得到一個Component,然后將其繪制展現。TableCellRenderer是一個接口,只有一個方法:
Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column)
其中,row和column標識一個單元格。也就是說,可以根據row和column的不同(單元格也就不同),獲得不同的填充組件,這樣只需要在該方法內進行相應的邏輯判斷。例如,可以實現同一列的不同行渲染效果不同,可以是單元格的背景色不同,或者是單元格內的字體不同諸如此類。下面的列子是,實現偶數行被划一道行線的效果:

- import java.awt.*;
- import javax.swing.*;
- import javax.swing.table.*;
- public class RoundColorTable extends JFrame {
- private String[] colname = {"第1列","第2列","第3列","第4列","第5列"}; //表頭信息
- private String[][] data = new String[10][5]; //表內容
- private JTable table;
- public RoundColorTable() {
- //表內容賦值
- for(int i = 0; i < 10; i++) {
- for(int j = 0; j < 5; j++) {
- data[i][j] = "( " + (j+1) + ", " + (i+1) + " )";
- }
- }
- table = new JTable(new DefaultTableModel(data,colname));
- TableCellRenderer tcr = new ColorTableCellRenderer();
- table.setDefaultRenderer(Object.class,tcr);//為JTable增加渲染器,因為是針對於表格中的所有單元格,所有用Object.class
- add(new JScrollPane(table),BorderLayout.CENTER);
- setVisible(true);
- setSize(500,300);
- setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- }
- public static void main(String args[]) {
- new RoundColorTable();
- }
- }
- class ColorTableCellRenderer extends DefaultTableCellRenderer
- {
- DefaultTableCellRenderer renderer=new DefaultTableCellRenderer();
- public Component getTableCellRendererComponent(JTable table, Object value,
- boolean isSelected, boolean hasFocus, int row, int column) {
- if(row%2 == 0){
- //調用基類方法
- return super.getTableCellRendererComponent(table, value, isSelected,hasFocus, row, column);
- }
- else{
- return renderer.getTableCellRendererComponent(table, value, isSelected,hasFocus, row, column);
- }
- }
- //該類繼承與JLabel,Graphics用於繪制單元格,繪制紅線
- public void paintComponent(Graphics g){
- super.paintComponent(g);
- Graphics2D g2=(Graphics2D)g;
- final BasicStroke stroke=new BasicStroke(2.0f);
- g2.setColor(Color.RED);
- g2.setStroke(stroke);
- g2.drawLine(0,getHeight()/2,getWidth(),getHeight()/2);
- }
- }
