网站已经改版为Wordpress版本,这里是旧版本的快照,请不要在页面中留言.

【JAVA】JTable学习之使用AbstractTableModel (二) 完结

    版权申明:本文出自悠然品鉴 小悠 原创,禁止伪原创抄袭,转载请注明出处:http://www.youranshare.com/blog/sid/68.html

 

接上一篇【JAVA】JTable学习之使用AbstractTableModel (一)

在上一篇的文章中 我们知道,JTable的表格和数据是分开的,每一个Jtable都会有自己的TableModel,在其内部都有一个二维 的Vector(假如是Vector TableData)用来存放二维的表格数据,每个表格都与这个二维的Vector形成映射关系,当表格Table显示的时候通过TableModel的接口 getRowcount(),getColumnCount(),获取表格的行数和列数生成一个能容纳TableData的数据表格,然后Table通过接口
getValueAt(int row,int col)获取到对应的表格位置的数据,这样表格就能对应显示出TableData中的所有数据了;

当我们修改表格的数据的时候,函数setValueAt(int row,int col)会被调用,我们只需要在这个函数中修改TableData中对应位置的数据,然后调用函数
 fireTableCellUpdated(int row,int col);更新一下表格对应位置的数据显示即可完成对表格的数据修改;


下面进入正题,设置Jtable的表格编辑器:
   我们知道如果在我们自己的TableModel中重载函数 boolean isCellEditable(int rowIndex, int columnIndex),并且设置其返回值为真的时候就可以使得对应的表格可编辑,也就是当我们双击表格的时候 可以进入一个编辑状态,如图:
                                                
仔细观察,这是一个 JTextFilied文本框,当我们按下Enter的时候即可完成编辑,表格又会变成正常的状态 

 

 看到这里我们对表格大致就已经有一个了解了, 简而言之就是:表格是表格,数据是数据,修改数据要通过一种【组件】来获取新的数据,例如我们要获得输入的文本,那么我们可以通过一个JTextFiled来获取文本的输入,输入完成后 将文本的内容递送到调用者即可完成数据的获取;


    
显示数据靠的是表格,存储数据靠的是TableModel,修改数据靠的是对应的编辑器,所谓的编辑器这也就是这篇文章所要说的 CellEditor表格编辑器、、在表的维护中是以列作为一个组的,所以对于表的每一列的数据类型必须是相同的,在默认状态下 即是我们不指定表的每一列的显示的数据类型的时候,TableModel中的数据将会被默认为String类型在Table中进行维护。

    下面我们举个例子,在表格内显示图片,与下拉列表JComboBox:


使用 JTable的3要素: 表格JTableModel编辑器


    
首先建立一个表格Model存放数据,为了简单起见,设置为 2x2的表格,第一列显示JComboBox、第二列显示图片

 

class MyTableModel extends AbstractTableModel
{        
  //表格的列标题   String head[]={"下拉列表","图片"};   //表格列属性,用于设置列的维护数据类型   Class[]TypeArr = {String.class,Icon.class};   //表格的数据   Object[][]data = {                                {"选项A",new ImageIcon("C://I//pic1.png")},                               {"选项B",new ImageIcon("C://I//pic2.png")}                            };
        //表格的行数  @Override
public int getRowCount()
{return 2;}
 //表格的列数
@Override
public int getColumnCount()
{return 2;}
//获取数据
@Override
public Object getValueAt(int rowIndex, int columnIndex)
{return data[rowIndex][columnIndex];}
  //获取表格每一列需要维护的数据类型
 @Override
public Class getColumnClass(int columnIndex)
  {return TypeArr[columnIndex]; }
//设置每个表格允许编辑
@Override
public boolean isCellEditable(int rowIndex, int columnIndex)
{return true;}
//表格的列标题
@Override
public String getColumnName(int column)
{return head[column];}
 //修改数据
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex)
{
  //修改Vector的数据 
data[rowIndex][columnIndex] = aValue;
//只需要更新对应的位置就行
this.fireTableCellUpdated(rowIndex, columnIndex);
}
}  // //
//************************************************************************自定义的图片编辑器
//实现 TableCellEditor,ActionListener 接口
class MyPicEditor extends AbstractCellEditor implements TableCellEditor,ActionListener
{
/*
*ReadMe:当我们点击表格Cell的时候,表格检测点击的消息,检测Cell是否允许编辑,
*如果允许编辑 则去调用 表格编辑器 来获取图片,获取完后将图片 送达给 TableModel
*结束编辑器的编辑状态,表格刷新显示 对应的图片
*/
//用于获取图片的变量
private Icon m_IconPic;
//作为 编辑器 ,当我们点击的时候进行图片的选择
private JButton m_IconButton;
//点击按钮的时候 进行文件选择的 Filechooser
private JFileChooser m_PicFileChooser;
//设置当我们 点击2次的时候 编辑器 才起作用
private static final int clickCountToStart = 2;
//构造函数,初始化一些信息
public MyPicEditor()
{
  m_IconButton =new JButton();
  m_IconButton.addActionListener(this);
  m_PicFileChooser = new JFileChooser();
}
//检测鼠标的点击次数,判断编辑器是否起作用
public boolean isCellEditable(EventObject anEvent) 
{
      //如果事件 是 鼠标的事件,大于设定的次数就true,否则false
      if (anEvent instanceof MouseEvent) 
      {
          System.out.println("检测鼠标的点击次数,设置编辑器是否响应");
           return ((MouseEvent)anEvent).getClickCount() >= clickCountToStart;
       }
       return false; 
 }
 
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column)
{
  System.out.println("表格Cell获取将要显示的编辑器组件,返回值编辑器包含的控件");
  //先前的表格Cell的 数据 先保存下来,用于初始化编辑器包含的控件的数据
  m_IconPic = (Icon)value;
  //返回作为编辑器的组件,这里是一个按钮
  return m_IconButton;
}
//响应编辑器包含的组件的事件
@Override
public void actionPerformed(ActionEvent e)
{
    System.out.println("编辑器组件事件响应");
    if(e.getSource()==m_IconButton)
    {
      //初始化编辑器,显示原始的图片
      m_IconButton.setIcon(m_IconPic);
      //显示文件选择器,用于选择图片
      m_PicFileChooser.showOpenDialog(m_IconButton);
       if(m_PicFileChooser.getSelectedFile()!=null)
       {
         //如果选择了新的图片将按钮设置为新的图标
         m_IconPic= new ImageIcon(m_PicFileChooser.getSelectedFile().getAbsolutePath());
       }
      //数据获取完成,终止编辑器,将数据送达 调用者
      this.fireEditingStopped();
    }
}
//将数据送达调用者,关闭编辑器,表格正常显示
@Override
public Object getCellEditorValue()
{
  System.out.println("返回结果");
  return m_IconPic;
}
}
// //下拉列表的编辑器
//****************************************************************Commbox的编辑器
class ComBoxEditor extends AbstractCellEditor implements TableCellEditor
{
/*
*ReadMe: 这个 ComboBox下拉列表的编辑器 使用一个 JLable 和一个 JComboBox组合的
*将JComboBox放到JLable里,所以只需要将 JLable 作为编辑器组件返回就行了
*/
private JComboBox m_ComboBox;
//获取 下拉列表的 选择的值
private String m_SelStr;
private JLabel m_OutLable;
//这里我们设置 鼠标点击 1 次就响应编辑器
private static final int clickCountToStart = 1;
 //初始化编辑器包含的控件信息
     public ComBoxEditor()     {  
    m_ComboBox = new JComboBox();
    m_ComboBox.addItem("选项A");
    m_ComboBox.addItem("选项B");
    m_ComboBox.addItem("选项C");
    m_ComboBox.setSize(100,30);
    m_OutLable= new JLabel();
    m_OutLable.setLayout(null);
    m_OutLable.setBounds(0, 0, 120, 40);
    m_OutLable.add(m_ComboBox);
    m_ComboBox.setLocation(50, 50);
//响应下拉列表的事件
m_ComboBox.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent e)
{
    System.out.println("下拉列表的选中事件");
    if(e.getStateChange() == e.SELECTED)
    {
    //获取选择的值
    m_SelStr = (String)m_ComboBox.getSelectedItem();
    //结束选择
    fireEditingStopped();
      }
           }
});
    }  
//检测鼠标的点击次数,判断编辑器是否起作用
   public boolean isCellEditable(EventObject anEvent)     {  
//如果事件 是 鼠标的事件,大于设定的次数就true,否则false
 if (anEvent instanceof MouseEvent) 
 {
    System.out.println("检测鼠标的点击次数,设置编辑器是否响应");
    return ((MouseEvent)anEvent).getClickCount() >= clickCountToStart;
 }
 return false;
   }  
 
//获取编辑器的组件
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column)
{
    System.out.println("获取编辑器的组件");
    //将下拉列表设置为之前的选项
    m_SelStr = (String)value;
    m_ComboBox.setSelectedItem(m_SelStr);
    //返回值为 null的时候 是空的编辑器,就是说 = =不允许 编辑的
    return m_OutLable;
}
//获取编辑器的 值
@Override
public Object getCellEditorValue()
{
     System.out.println("返回结果");
     return m_SelStr;
  }
} // // // TabelMode、编辑器都有了,我们只需要 一个JTable 显示一下就Ok了  //****************************************************定义显示表格的Frame
public class CellEditorFrame 
{
    public static void main(String[]sre)
   {
      MyTableModel m_TableModel = new MyTableModel();
 
      JTable m_TableDemo = new JTable(m_TableModel);
      //定义两个编辑器
      ComBoxEditor m_ComboBoxEditor = new ComBoxEditor();
      MyPicEditor m_PicEditor =new MyPicEditor();
 
      JFrame m_MyFrame = new JFrame("我的CellEditor");
      //为每一列 设置编辑器
      m_TableDemo.getColumnModel().getColumn(0).setCellEditor(m_ComboBoxEditor);
      m_TableDemo.getColumnModel().getColumn(1).setCellEditor(m_PicEditor);
       //设置行高
      m_TableDemo.setRowHeight(200);
 
      JScrollPane m_JScroolPanel = new JScrollPane(m_TableDemo);
      m_JScroolPanel.setViewportView(m_TableDemo);
      m_JScroolPanel.setSize(480, 200);
 
      m_MyFrame.add(m_JScroolPanel);
      m_MyFrame.setBounds(200, 200, 500, 500);
      m_MyFrame.setDefaultCloseOperation(m_MyFrame.EXIT_ON_CLOSE);
      m_MyFrame.setVisible(true);
   }
 
}


OK AbstractTableModel教程到此结束,下面是效果图

 

 

 

附加上一个源代码文件:CellEditor.java

解压密码 yscode

百度网盘下载地址:http://pan.baidu.com/s/1c0xRzDe



 版权申明:本文出自悠然品鉴 小悠 原创,禁止伪原创抄袭,转载请注明出处:http://www.youranshare.com/blog/sid/68.html



  • 标签:
  • JTable AbstractTabl
  • AbstractTabl显示控件
  • AbstractTabl显示图片
网站已经改版为Wordpress版本,这里是旧版本的快照,请不要在页面中留言.