so true

心怀未来,开创未来!
随笔 - 160, 文章 - 0, 评论 - 40, 引用 - 0
数据加载中……

JTable学习笔记

构建一个JTable之前,应该设计好表格的列头以及行数据,分别用final数组保存之:
final String [] names={"First Name","Last Name","Favorite Color",
            "Favorite Number","Vegetarian"};
final Object [][] data={
    {"Mark","Andrews","Red",new Integer(2),new Boolean(true)},
    {"Tom","Chung","Green",new Integer(99),new Boolean(false)}
    };
接下来,在创建JTable之前,需要构建一个实现了TableModel接口的AbstractTableModel类的实例,TableModel接口规定了JTable如何访问表格中数据的模型。示例如下:
TableModel dataModel =new AbstractTableModel(){
        public int getColumnCount(){return names.length;}//实现这个函数是必须的,因为抽象类AbstractTableModel中并没有实现该函数
        public int getRowCount(){return data.length;}//实现这个函数是必须的,因为抽象类AbstractTableModel中并没有实现该函数
        public Object getValueAt(int row,int col){return data[row][col];}//实现这个函数是必须的,因为抽象类AbstractTableModel中并没有实现该函数
        public String getColumnName(int column){return names[column];}//如果需要自己来命名列名称,就必须override该方法
        @SuppressWarnings("unchecked")
        public Class getColumnClass(int col){return getValueAt(0,col).getClass();}//这个方法也因该重写,因为AbstractTableModel中的实现仅仅是“return Object.class;”,因此我们需要override该方法
        public boolean isCellEditable(int row,int col){return true;}//默认均返回false,因此如果希望表格的cell能够被编辑,就需要override这个函数
        public void setValueAt(Object aValue,int row,int col){//默认情况下,该函数的函数体是空的,因此如果希望表格的cell中的值能够被更改,就必须override该函数
            System.out.println("Setting value to: "+aValue);
            data[row][col]=aValue;
        }
};
接下来就可以创建JTable了:
JTable tableView=new JTable(dataModel);
至此,表格已经创建起来了。如果需要能够对表格进行更进一步的操作,比如允许用户编辑表格中各个单元格的内容,就需要看看下面的内容喽:
我个人认为编辑表格是以列为单位的,
第一步,需要得到某一列:
TableColumn colorColumn=tableView.getColumn(names[2]);
第二步,需要给该列指定一个实现了TableCellEditor接口的编辑类,DefaultCellEditor类实现了该接口,因此直接构建DefaultCellEditor类的一个实例就ok了,需要说明的是,该类的实现方法只有三种,而且分别对应需要JCheckBox、JComboBox、JTextField三种类的实例:
colorColumn.setCellEditor(new DefaultCellEditor(comboBox));
第三步,给该列指定一个实现了TableCellRenderer接口的的渲染类(或称作呈现/表现类),DefaultTableCellRenderer类实现了该接口,因此直接构建DefaultTableCellRenderer的一个实例就ok了:
DefaultTableCellRenderer colorColumnRenderer=new DefaultTableCellRenderer();
        colorColumnRenderer.setBackground(Color.pink);
        colorColumnRenderer.setHorizontalAlignment(JLabel.RIGHT);
        colorColumnRenderer.setToolTipText("Click for combo box");
        colorColumn.setCellRenderer(colorColumnRenderer);
需要说明的是,DefaultTableCellRenderer能够设置的内容当然不局限于上述列出的这三个,还有很多,但是有一点很重要,就是如果你希望单元格的内容能够按照某种方式来改变,比如用户自己编辑了单元格内容后,我们如果希望单元格呈现的内容能够根据用户的输入做更多的变化(而不仅仅是简单的字符串替换,如果仅仅是字符串替换的话,那就不必废这么多事了,DefaultTableCellRenderer类自带的setValue实现方法就能够完成任务了),而不在希望单元格的内容一成不变了,此时就不能简单的创建一个DefaultTableCellRenderer类的实例了,而是需要创建一个DefaultTableCellRenderer类的派生类,而且需要override里面的setValue方法,通常我们都这样做:
DefaultTableCellRenderer numberColumnRenderer=new DefaultTableCellRenderer(){
        public void setValue(Object value){
            int cellValue=(value instanceof Number) ? ((Number)value).intValue() : 0;
            this.setForeground((cellValue > 30) ? Color.black : Color.red);
            super.setValue(value);
        }
};
在DefaultTableCellRenderer类中setValue方法的修饰符为protected,因此我们不能直接用DefaultTableCellRenderer的实例来使用该方法,而只能通过继承DefaultTableCellRenderer类,然后在类的内部override该方法来实现定制特定的功能,从这里我们也能够更深刻的理解为什么有些方法要定义成protected了,目的就是为了对外不可见,但是又能够通过继承的手段来实现用户自己的定制,而且有些情况这是很必须的,比如在该处,我们可以试想一下,如果用public来修饰,则用户可以直接通过产生实例来引用该方法,那么由于该类是作用于整个列的,而不仅仅是一个单元格,那么当你设定了setValue后,到底是该对列中所有的单元格都有效呢,还是该只对某一个单元格有效呢,这就很难说了。

posted on 2007-12-20 23:20 so true 阅读(1026) 评论(0)  编辑  收藏 所属分类: Java


只有注册用户登录后才能发表评论。


网站导航: