swing JTable学习(三):AbstractTableModel

swing JTable学习(三):AbstractTableModel如同其它的Swing组件,JTable使用MVC(模型、试图、控制器)设计方式,将可视化组件(JTable实例)从其数据(TableModel实现)中分离出来。·TableModel接口1、TableModel为JTable提供·显示的数据·表格的维数·表格中每一列所包含的数据类型·应该显示的列标题·是否允许编辑指定单元格的值2、实现TableModel:Tab

 

如同其它的Swing组件,JTable使用MVC(模型、试图、控制器)设计方式,将可视化组件(JTable实例)从其数据(TableModel实现)中分离出来。

·TableModel接口

1、TableModel为JTable提供

·显示的数据

·表格的维数

·表格中每一列所包含的数据类型

·应该显示的列标题

·是否允许编辑指定单元格的值

2、实现TableModel:

TableValues类

 

import javax.swing.table.AbstractTableModel;
/** 
 *     注意:一般使用AbstractTableModel创建TableModel的实现,只有少量数据时使用DefaultTableModel,
 */
public class TableValues extends AbstractTableModel{

         private static final long serialVersionUID = -8430352919270533604L;
         public final static int NAME = 0;
         public final static int GENDER = 1;
         public final static String[] columnNames = {“姓名”, “性别”};
         public Object[][] values = {

                            {“Cannel_2020”,true},
                            {“Lucy”,false},
                            {“韩梅”,false},
                            {“李雷”,true},
                            {“Jim”,true}
         };
         publicint getColumnCount() {

                   return  values[0].length;
         }
         publicint getRowCount() {

                   return values.length;
         }
         public Object getValueAt(int rowIndex, int columnIndex) {

                   return values[rowIndex][columnIndex];
         }

         /**
          * 获取列名
          */
         publicString getColumnName(int column){

                   return columnNames[column];
         }
} 

SimpleTableTest类

 

import java.awt.BorderLayout;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class SimpleTableTest extends JFrame{

       
         private static final long serialVersionUID = -4172876583187222326L;
         protected JTable table;
         public SimpleTableTest(){

                   Container pane = getContentPane();
                   pane.setLayout(newBorderLayout());

                   TableValues tv =  new TableValues();
                   table= new JTable(tv);

                   //设置行高
                   table.setRowHeight(30);
                   //必须把table放入JScrollPane才会有列名出现
                   JScrollPane jsp = new JScrollPane(table);
                   pane.add(jsp,BorderLayout.CENTER);
         }
         publicstatic void main(String[] args) {

                   SimpleTableTeststt = new SimpleTableTest();
                   stt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                   stt.setSize(400,200);
                   stt.setVisible(true);
         }
} 

运行结果:

swing JTable学习(三):AbstractTableModel

·实现TableCellRenderer(单元格渲染器)接口

1、使表格“性别”一列的单元格出现JComboBox组件

GenderRenderer类

 

import java.awt.Component;
import javax.swing.JComboBox;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
 
public class GenderRenderer extendsJComboBox implements TableCellRenderer{

         privatestatic final long serialVersionUID = -8624401777277852691L;
         publicGenderRenderer(){

                   super();
                   addItem(“男”);
                   addItem(“女”);
         }
         publicComponent getTableCellRendererComponent(JTable table, Object value,
                            booleanisSelected, boolean hasFocus, int row, int column) {

                   if(isSelected){

                            setForeground(table.getForeground());
                            super.setBackground(table.getBackground());
                   }else{

                            setForeground(table.getForeground());
                            setBackground(table.getBackground());
                   }
                   booleanisMale = ((Boolean)value).booleanValue();
                   setSelectedIndex(isMale? 0 : 1);
                   returnthis;
         }
 
} 

2、SimpleTableTest类的构造函数改变如下:

 

public SimpleTableTest(){

                   setTitle(“FromCannel_2020’s blog(CSDN)”);
                   setLayout(newBorderLayout());
                   TableValuestv =  new TableValues();
                   table= new JTable(tv);
                   //设置行宽
                   table.setRowHeight(30);
                 
                   TableColumnModeltcm= table.getColumnModel();
                   TableColumntc = tcm.getColumn(TableValues.GENDER);
                   //设置“性别”列的单元格渲染器(renderer)
                   tc.setCellRenderer(newGenderRenderer());
                 
                   //必须把table放入JScrollPane才会有列名出现
                   JScrollPanejsp = new JScrollPane(table);
                   add(jsp,BorderLayout.CENTER);
         } 

运行结果:

swing JTable学习(三):AbstractTableModel

3、注意:渲染器实际上并没有像可视化组件添加到Container中那样添加到JTable实例中,即表格中不含有JComboBox实例。此时,是将唯一的JComboBox实例绘制(通过向paint()方法传递Graphics对象)到“性别”一列的每一个单元格所占用的区域中。

4、在TableValues添加如下代码(覆盖AbstractTableModel中的方法),使得JTable实例中单元格可以编辑:

 

    /**
     * 设置单元格可以编辑
     */
    public booleanisCellEditable(int row, int column){

       returntrue;
    } 

然而此时对“性别”一列的单元格进行编辑,会出现如下情况:

swing JTable学习(三):AbstractTableModel

这就得使用到单元格编辑器了。

·实现TableCellEditor(单元格编辑器)接口

1、

 

import java.awt.Component;
import java.util.EventObject;
import javax.swing.JComboBox;
import javax.swing.JTable;
importjavax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.EventListenerList;
import javax.swing.table.TableCellEditor;
 
public class GenderEditor extends JComboBoximplements TableCellEditor{

       
         privatestatic final long serialVersionUID = 5860619160549087886L;
         //EventListenerList:保存EventListener 列表的类。
         privateEventListenerList listenerList = new EventListenerList();
         //ChangeEvent用于通知感兴趣的参与者事件源中的状态已发生更改。
         privateChangeEvent changeEvent = new ChangeEvent(this);
         publicGenderEditor(){

                   super();
                   addItem(“男”);
                   addItem(“女”);
                   //请求终止编辑操作可以包含单元格的JTable收到,也可以从编辑器组件本身(如这里的JComboBox)获得
                   /*addActionListener(newActionListener(){

                            publicvoid actionPerformed(ActionEvent e) {

                                     System.out.println(“ActionListener”);
                                     //如同stopCellEditing,都是调用fireEditingStopped()方法
                                     fireEditingStopped();
                            }
                          
                   });*/
         }
         publicvoid addCellEditorListener(CellEditorListener l) {

                   listenerList.add(CellEditorListener.class,l);
         }
         publicvoid removeCellEditorListener(CellEditorListener l) {

                   listenerList.remove(CellEditorListener.class,l);
         }
         privatevoid fireEditingStopped(){

                   CellEditorListenerlistener;
                   Object[]listeners = listenerList.getListenerList();
                   for(inti = 0; i < listeners.length; i++){

                            if(listeners[i]== CellEditorListener.class){

                                     //之所以是i+1,是因为一个为CellEditorListener.class(Class对象),
                                     //接着的是一个CellEditorListener的实例
                                     listener= (CellEditorListener)listeners[i+1];
                                     //让changeEvent去通知编辑器已经结束编辑
                           <span style=”white-space:pre”> </span>     //在editingStopped方法中,JTable调用getCellEditorValue()取回单元格的值,
                                     //并且把这个值传递给TableValues(TableModel)的setValueAt()
                                     listener.editingStopped(changeEvent);
                            }
                   }
         }
         publicvoid cancelCellEditing() {        
         }
         /**
          * 编辑其中一个单元格,再点击另一个单元格时,调用。————-!!!!!
          */
         publicboolean stopCellEditing() {

                   //可以注释掉下面的fireEditingStopped();,然后在GenderEditor的构造函数中把
                   //addActionListener()的注释去掉(这时请求终止编辑操作从JComboBox获得),
                   System.out.println(“编辑其中一个单元格,再点击另一个单元格时,调用。”);
                   fireEditingStopped();//请求终止编辑操作从JTable获得
                   returntrue;
         }
         /**
          * 为一个单元格初始化编辑时,getTableCellEditorComponent被调用
          */
         publicComponent getTableCellEditorComponent(JTable table, Object value,
                            booleanisSelected, int row, int column) {

                   booleanisMale = ((Boolean)value).booleanValue();
                   setSelectedIndex(isMale? 0 : 1);
                   returnthis;
         }
         /**
          * 询问编辑器它是否可以使用 anEvent 开始进行编辑。
          */
         publicboolean isCellEditable(EventObject anEvent) {

                   returntrue;
         }
         /**
          * 如果应该选择正编辑的单元格,则返回true,否则返回 false。
          */
         publicboolean shouldSelectCell(EventObject anEvent) {

                   returntrue;
         }
 
         /**
          * 返回值传递给TableValue(TableModel)中的setValueAt()方法
          */
         publicObject getCellEditorValue() {

                   returnnew Boolean(getSelectedIndex() == 0 ? true : false);
         }
} 

2、SimpleTableTest类的构造函数中

 

tc.setCellRenderer(new GenderRenderer()); 

后面加入:

 

//设置“性别”列的单元格编辑器(editor)
tc.setCellEditor(new GenderEditor()); 

运行结果:

swing JTable学习(三):AbstractTableModel

3、还有一点别忘了再在TableValues加入如下代码(原因:看第4的最后一点

       /**
          * 单元格被编辑完后,调用此方法更新值
          */
         publicvoid setValueAt(Object value, int row, int column){

                   values[row][column]= value;
         }

4、GenderEditor类的工作流程:

1)、调用TableCellEditor接口中的getTableCellEditorComponent()方法初始化编辑

2)、编辑当前的单元格,再点击另一个单元格时,调用CellEditor中的stopCellEditing(),通过fireEditingStopped()调用到editingStopped()。

3)、在editingStopped方法中,JTable调用getCellEditorValue()取回单元格的值,并且把这个值传递给TableValues(TableModel)的setValueAt()

今天的文章swing JTable学习(三):AbstractTableModel分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/30917.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注