JTable组件使用的是模型/视图/控制器的设计方式,将可视化组件从其数据中分离出来,因此表格中的数据都封装在数据模型中。其中最重要的支持类就是TableModel类,这个类用来定义JTable类以及其数据模型之间的接口。
1 import java.awt.*; 2 import javax.swing.*; 3 public class SimpleTableTest extends JFrame{ 4 5 private static final long serialVersionUID = 1L; 6 protected JTable table; 7 protected Object[][] data; 8 protected String[] colname = {"编号","书名","作者","主角","类别","选择"}; 9 public SimpleTableTest(){ 10 Container pane = getContentPane(); 11 pane.setLayout(new BorderLayout()); 12 createTableData(); //创建表格所需数据 13 table = getSimpleTable(); 14 JScrollPane jsPane = new JScrollPane(table); 15 pane.add(jsPane,BorderLayout.CENTER); 16 } 17 public void createTableData(){ 18 data = new Object[10][6]; 19 int i =0; 20 data[i++] = new Object[]{"01","射雕英雄传","金庸","郭靖","武侠",true}; 21 data[i++] = new Object[]{"02","神雕侠侣" ,"金庸","杨过","武侠",false}; 22 data[i++] = new Object[]{"03","笑傲江湖" ,"金庸","令狐冲","武侠",true}; 23 data[i++] = new Object[]{"04","鹿鼎记" ,"金庸","韦小宝","武侠",false}; 24 data[i++] = new Object[]{"05","大旗英雄传" ,"古龙","铁中棠","武侠",false}; 25 data[i++] = new Object[]{"06","陆小凤传奇" ,"古龙","陆小凤","武侠",false}; 26 data[i++] = new Object[]{"07","多情剑客无情剑" ,"古龙","李寻欢","武侠",false}; 27 data[i++] = new Object[]{"08","三国演义" ,"罗贯中","无","古典名著",false}; 28 data[i++] = new Object[]{"09","封神演义" ,"陈仲琳","无","古典名著",false}; 29 data[i++] = new Object[]{"10","绿野仙踪" ,"李百川","冷于冰","古典名著",false}; 30 } 31 public static void main(String[] args){ 32 SimpleTableTest stt= new SimpleTableTest(); 33 stt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 34 stt.setSize(400, 200); 35 stt.setVisible(true); 36 } 37 /** 38 * 返回一个简单的表格 39 * @return 40 */ 41 public JTable getSimpleTable(){ 42 table = new JTable(data,colname); 43 return table; 44 } 45 }
运行结果如下图所示:
虽然没有创建表格模型,但是JTable的构造函数默认创建了一个表格模型。
1 public JTable(final Object[][] rowData, final Object[] columnNames) { 2 this(new AbstractTableModel() { 3 public String getColumnName(int column) { return columnNames[column].toString(); } 4 public int getRowCount() { return rowData.length; } 5 public int getColumnCount() { return columnNames.length; } 6 public Object getValueAt(int row, int col) { return rowData[row][col]; } 7 public boolean isCellEditable(int row, int column) { return true; } 8 public void setValueAt(Object value, int row, int col) { 9 rowData[row][col] = value; 10 fireTableCellUpdated(row, col); 11 } 12 }); 13 }
该构造函数实现了AbstractTableModel类。上述六种方法的作用是:返回表格的列名,返回行数,返回列数,返回特定单元格的值,判断特定单元格是否可编辑,设置特定单元格的值。
另外Java也提供了另外一种类DefaultTableModel类来实现TableModel接口。
简单来说,DefaultTableModel使用起来要容易一些,但是DefaultTableModel在使用时会将所有的数据加载到内存中,因此适合表格中只含有少量数据时使用。而AbstractTableModel适合显示大量数据时使用,它不会将所有数据都载入内存,只有在需要时才会加载数据,从而最小限度的使用内存。
1 /** 2 * 设置表格风格 3 * @param tb 4 */ 5 public void setSimpleTableStyle(JTable tb){ 6 //设置表头的背景色 7 tb.getTableHeader().setBackground(Color.BLUE); 8 //设置表头的文字颜色 9 tb.getTableHeader().setForeground(Color.RED); 10 //设置表头字体 11 tb.getTableHeader().setFont(new Font("隶书",Font.PLAIN,14)); 12 // 设置行高 13 tb.setRowHeight(30); 14 table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); 15 table.getColumn(colname[0]).setPreferredWidth(150); //设置第1列的宽度 16 table.getColumn(colname[1]).setPreferredWidth(140); //设置第2列的宽度 17 table.setBackground(new Color(244, 244, 242)); //设置表格背景 18 tb.setForeground(Color.GREEN); //设置表格颜色 19 tb.setFont(new Font("隶书",Font.PLAIN,14)); //设置表格字体 20 // 隐藏最后一列 21 table.getColumn(colname[colname.length - 1]).setMaxWidth(0); 22 table.getColumn(colname[colname.length - 1]).setMinWidth(0); 23 table.getColumn(colname[colname.length - 1]).setPreferredWidth(0); 24 //设置表格的自动调整模式 25 table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 26 //设置表格的行选择模式 27 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 28 //设置是否允许选择表格行 29 table.setRowSelectionAllowed(true); 30 //设置是否允许选择表格列 31 table.setColumnSelectionAllowed(true); 32 //设置是否允许同时存在行选择与列选择 33 table.setCellSelectionEnabled(true); 34 }
运行结果:
需要注意的是getColumn()方法是通过列名来获取对应列的TableColumn对象,当表格中有相同列名时只返回最先匹配列的TableColumn对象。你可以在列名前后加上空格用来区分。