图解应用集成开发环境设计GUI程序-3
效果如下图:
程序代码清单如下:
1 package com.javaapp.ch12; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import javax.swing.*; 6 import javax.swing.table.*; 7 @SuppressWarnings("serial") 8 public class FrameTableDemo extends JFrame { 9 private boolean DEBUG = true; 10 @SuppressWarnings("static-access") 11 public FrameTableDemo() { 12 // 实现构造方法 13 super("计应14职位表"); // 首先调用父类JFrame的构造方法生成一个窗口 14 MyTableModel myModel = new MyTableModel(); // myModel存放表格的数据 15 JTable table = new JTable(myModel); // 表格对象table的数据来源是myModel对象 16 table.setPreferredScrollableViewportSize(new Dimension(400,100)); 17 // 表格的显示尺寸 18 table.setAutoResizeMode(table.AUTO_RESIZE_OFF);// 设置自动横向滚动 19 TableColumnModel md7 = (TableColumnModel) table.getColumnModel(); 20 md7.getColumn(0).setMinWidth(30);// 设置列的宽度 21 md7.getColumn(1).setMaxWidth(50); 22 md7.getColumn(2).setMaxWidth(60); 23 JScrollPane scrollPane = new JScrollPane(table);// 产生一个带滚动条的面板 24 table.setRowMargin(2);//设置表格线的宽度 25 table.setRowHeight(40);//设置行的高度 26 getContentPane().add(scrollPane,BorderLayout.CENTER); 27 // 将带滚动条的面板添加入窗口中 28 addWindowListener(new WindowAdapter() { 29 public void windowClosing(WindowEvent e)// 注册窗口监听器 30 { 31 System.exit(0); 32 } 33 }); 34 } 35 // 把要显示在表格中的数据存入字符串数组和Object数组中 36 class MyTableModel extends AbstractTableModel { 37 // 表格中第一行所要显示的内容存放在字符串数组columnNames中 38 final String[] columnNames = { "像片","姓名","职位","电话","工资","婚否" }; 39 // 表格中各行的内容保存在二维数组data中 40 ImageIcon apple = createImageIcon("4.jpg","天峰像片");//图片放在与本类同一目录中 41 ImageIcon anther = createImageIcon("5.jpg","其它像片"); 42 ImageIcon apple1 = createImageIcon("6.jpg","天峰像片"); 43 ImageIcon anther2 = createImageIcon("7.jpg","其它像片"); 44 final Object[][] data = { 45 { apple,"天峰","自由作家","02988225560",new Integer(20), 46 new Boolean(false) }, 47 { anther,"娜娜","总经理秘书","01068939397",new Integer(5000), 48 new Boolean(true) }, 49 { apple1,"沙沙","CEO","02983079137",new Integer(5500), 50 new Boolean(false) }, 51 { anther2,"杨深刚","科长","0296887678",new Integer(6000), 52 new Boolean(true) }, 53 { apple1,"李少恒","财务科长 ","02933541290",new Integer(4000), 54 new Boolean(false) } }; 55 // 下述方法是重写AbstractTableModel中的方法,其主要用途是被JTable对象调用,以便在表格中正确的显示出来。程序员必须根据采用的数据类型加以恰当实现。 56 // 获得列的数目 57 public int getColumnCount() { 58 return columnNames.length; 59 } 60 // 获得行的数目 61 public int getRowCount() { 62 return data.length; 63 } 64 // 获得某列的名字,而目前各列的名字保存在字符串数组columnNames中 65 public String getColumnName(int col) { 66 return columnNames[col]; 67 } 68 // 获得某行某列的数据,而数据保存在对象数组data中 69 public Object getValueAt(int row,int col) { 70 return data[row][col]; 71 } 72 // 判断每个单元格的类型 73 public Class getColumnClass(int c) { 74 return getValueAt(0,c).getClass(); 75 } 76 // 将表格声明为可编辑的 77 public boolean isCellEditable(int row,int col) { 78 if (col < 2) { 79 return false; 80 } else { 81 return true; 82 } 83 } 84 // 改变某个数据的值 85 public void setValueAt(Object value,int row,int col) { 86 if (DEBUG) { 87 System.out.println("设置值在 " + row + ", " + col + " to " + value 88 + " (an instance of " + value.getClass() + ")"); 89 } 90 if (data[0][col] instanceof Integer && !(value instanceof Integer)) { 91 try { 92 data[row][col] = new Integer(value.toString()); 93 fireTableCellUpdated(row,col); 94 } catch (NumberFormatException e) { 95 JOptionPane.showMessageDialog(FrameTableDemo.this,"The \"" 96 + getColumnName(col) + "\" 列只接受整型数据."); 97 } 98 } else { 99 data[row][col] = value; 100 fireTableCellUpdated(row,col); 101 } 102 if (DEBUG) { 103 System.out.println("数据的最新改变值:"); 104 printDebugData(); 105 } 106 } 107 public ImageIcon createImageIcon(String filename,String description) { 108 String path = filename; 109 return new ImageIcon(getClass().getResource(path),description); 110 } 111 private void printDebugData() { 112 int numRows = getRowCount(); 113 int numCols = getColumnCount(); 114 for (int i = 0; i < numRows; i++) { 115 System.out.print(" row " + i + ":"); 116 for (int j = 0; j < numCols; j++) { 117 System.out.print(" " + data[i][j]); 118 } 119 System.out.println(); 120 } 121 System.out.println("--------------------------"); 122 } 123 } 124 public static void main(String[] args) { 125 FrameTableDemo frame = new FrameTableDemo(); 126 frame.pack(); 127 frame.setVisible(true); 128 } 129 }
程序分析:
在上面的FrameTableDemo类中,通过自定义一个内部类MyTableModel来定义表格数据,MyTableModel类继承AbstractTableModel类,并重写了AbstractTableModel类中的getColumnCount、getRowCount、getColumnName、getValueAt方法。
一个表格通常由两部分构成,一部分为表头显示的标题数据,另一部分为每一行显示的数据。表头数据需要放在一个一维的字符串数组中,定义表头的方法为:
1 fianl String[] columnName={"像片","姓名","职位","电话","工资","婚否"};
而表格中的行数据实一个任意类型的二维数组,例如在上面的程序中,定义表格的行数据的方法为:
1 fianl Object[][] data={ 2 {apple,"天峰","自由作家","02988225560",new Integer(20),new Boolean(false)}};
AbstractTableModel类中主要的方法有:
1,获得表格中列数的方法getColumnCount() 该方法一般需要重写,它返回表格中的列数,即上面程序中下定义的columnNames的长度。
2,获得表格中行数的方法getRowCount() 该方法一般也需要重写,它返回表格中的行数,即上面程序中下定义的data的长度。
3,获得表格中某列名字的方法getColumnName(int col) 该方法根据传入的列号返回对应表格头的列名,即上面程序中下定义的columnNames中的值,一般也需要重写。
4,获得某行某列数据的方法getValueAt(int row,int col) 该方法根据传入的行号好列号返回对应的值,即上面程序中下定义的data中的值,一般也需要重写。
5,设置表格的某行某列数据是否可编辑的方法isCellEditable(int row,int col) 如果该方法返回的值是true,则表明相对应的表格数据是可编辑的,否则是不可编辑的。
6,改变表格中某行某列数据值的方法 setValueAt(Object value, int row, int col) 通过该方法可以更改表格中相对应的值,即上面程序中下定义的data中的值,一般也需要重写。
当创建问完AbstractTableModel的子类后,可以直接用它来创建表格,创建表格的方法为:
1 MyTableModel myModel=enw MyTableModel; //myModel存放表格的数据 2 Jtable table=new JTable(myModel); //表格对象data的数据来源是myModel对象
创建完表后,需要把表格放在JScollPane面板中显示,实现代码为:
1 JScrollPane scrollPane=new JScrollpane(table); //产生一个带滚动条的面板 2 table.setAutoResizeMode(table.AUTO_RESIZE_OFF); //设置自动横向滚动
可以通过TableColumnModel对象来设置表中没列的列宽,TableColumnModel对象的获取和设置列宽的方法为:
1 TableColumnModel mf7=(TableColumnModel)table.getColumnModel(); 2 md7.getColumn(0).setMinWidth(30); //设置列宽