转载: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);
- }
- }