JTable填充模型有两种方式,一种是构造JTable时指定行数组和列名数组,这种方式数据会以字符串的形式显示在表格中,因为模型得到的所有列的类型都为String。另一种方式是用TableModel填充表格。应该覆盖getColumnClass方法让模型得到每一列的正确类型。此时值为boolean类型的单元格会绘制为JCheckBox,String类型的值会绘制为JLabel(默认绘制器)。如果有其他类型的值,如Color,还是会绘制为JLabel,因为Color没有默认的绘制器。如果想以自己的形式绘制Color,需要定制自己的绘制器。JTable类中有一个Hashtable用来保存所有的类型和绘制器的关联,调用JTable的setDefaultRenderer方法可以将类型和默认绘制器关联。绘制器是一个实现了TableCellRenderer接口的对象,该接口只有一个方法 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)。当单元格需要绘制时就会使用这个方法的返回值绘制单元格。如果想绘制Color类型的数据可以在这个方法中返回一个带颜色的面板。
自定义绘制器代码:
package com.swing.table;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.EventObject;
import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
import com.swing.base.SuperFrame;
/**
* This program demonstrates how to show a simple table
* @version 1.11 2007-08-01
* @author Cay Horstmann
*/
public class TableTest {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame frame = new PlanetTableFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
/**
* This frame contains a table of planet data.
*/
class PlanetTableFrame extends SuperFrame {
public PlanetTableFrame() {
setTitle("TableTest");
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
TableModel model = new MyTableModel();
final JTable table = new JTable(model);
table.setAutoCreateRowSorter(true);// 自动排序
table.setFillsViewportHeight(true);// 填充视口
table.setDefaultRenderer(Color.class, new ColorRender());// 设置渲染器
//table.setDefaultEditor(Color.class, new ColorTableCellEditor());// 设置编辑器
table.setRowSelectionAllowed(false);
add(new JScrollPane(table), BorderLayout.CENTER);
JButton printButton = new JButton("Print");
printButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
try {
table.print();
} catch (java.awt.print.PrinterException e) {
e.printStackTrace();
}
}
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(printButton);
add(buttonPanel, BorderLayout.SOUTH);
}
// 颜色单元格绘制器
private class ColorRender extends JPanel implements TableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
setBackground((Color) value);
if (hasFocus)
setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
else
setBorder(null);
return this;
}
}
// 颜色单元格编辑器
private class ColorTableCellEditor extends AbstractCellEditor implements TableCellEditor {
public ColorTableCellEditor() {
panel = new JPanel();
chooser = new JColorChooser();
dialog = JColorChooser.createDialog(null, "Planet Color", false, chooser, new ActionListener() {
public void actionPerformed(ActionEvent e) {
stopCellEditing();// 会调用getCellEditorValue方法的值更改模型数据
}
}, new ActionListener() {
public void actionPerformed(ActionEvent e) {
cancelCellEditing(); }
});
dialog.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
cancelCellEditing();
}
});
}
// 编辑单元格时这个组件会暂时取代绘制器
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
chooser.setColor((Color) value);
return panel;
}
@Override
public boolean shouldSelectCell(EventObject anEvent) {
dialog.setVisible(true);
return true;
}
@Override
public void cancelCellEditing() {
dialog.setVisible(false);
super.cancelCellEditing();
}
@Override
public boolean stopCellEditing() {
dialog.setVisible(false);
super.stopCellEditing();
return true;
}
public Color getCellEditorValue() {
return chooser.getColor();
}
@Override
public boolean isCellEditable(EventObject e) {
// TODO 自动生成方法存根
return true;
}
private JColorChooser chooser;
private JDialog dialog;
private JPanel panel;
}
private static final int DEFAULT_WIDTH = 400;
private static final int DEFAULT_HEIGHT = 200;
}
class MyTableModel extends AbstractTableModel {
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
return cells.length;
}
public Object getValueAt(int rowIndex, int columnIndex) {
return cells[rowIndex][columnIndex];
}
@Override
public String getColumnName(int column) {
// TODO 自动生成方法存根
return columnNames[column];
}
@Override
//如果不覆盖这个方法每列的类型都为String
public Class<?> getColumnClass(int columnIndex) {
return cells[0][columnIndex].getClass();
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
cells[rowIndex][columnIndex] = aValue;
}
private Object[][] cells = { { "Mercury", 2440.0, 0, false, Color.YELLOW },
{ "Venus", 6052.0, 0, false, Color.YELLOW }, { "Earth", 6378.0, 1, false, Color.BLUE },
{ "Mars", 3397.0, 2, false, Color.RED }, { "Jupiter", 71492.0, 16, true, Color.ORANGE },
{ "Saturn", 60268.0, 18, true, Color.ORANGE }, { "Uranus", 25559.0, 17, true, Color.BLUE },
{ "Neptune", 24766.0, 8, true, Color.BLUE }, { "Pluto", 1137.0, 1, false, Color.BLACK } };
private String[] columnNames = { "Planet", "Radius", "Moons", "Gaseous", "Color" };
}
可以看到布尔类型和Color类型的值都使用了绘制器