第三节:高级Swing界面JTable编程

本文详细讲解了如何使用Java Swing的JTable组件结合TableModel进行高级界面编程。内容涵盖JTable与TableModel的关系、如何自定义TableModel显示数据、表格的美化方法,包括设置宽度高度、显示表头、下拉框列以及实现表格排序。此外,还介绍了JTable的事件响应和一个基于JTable的《java连连看》游戏的初步设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                                                  第三节:高级Swing界面JTable编程

目标:

1. 掌握表格组件的基本用法;

2. 理解数据结构与界面分离的设计原理

1.JTableTableModel 2

1TableModelJTable的关系: 2

2.TableModel实践: 3

3.使用JTable+TableModel展示java中的数据对象: 4

2.JTable展示方式的美化: 7

1.设置表格的宽度和高度: 7

2.要显示表头: 8

3.新加列,将列设为下拉框: 8

4.表格排序: 9

3. JTable事件响应和项目设想 9

4.一个游戏:《java连连看》 10

1.需求分析: 10

2.编写TableModel和界面实现: 11

3.连连看事件监听: 14

总结和任务: 15

1.JTable与TableModel

1TableModelJTable的关系:

前面,我们己学会在界面上加入一个简单的JTable对象:

JTable table=new JTable(3,5);这段代码即可创建一个三行五列的表格用以显示在界面上;在具体的应用中,我们肯定是要让JTable显示我们自己定义的数据,比如将上例中的UserInfo对象或UserBlog对象显示到表格中,那就必须定制JTable对象所要使用的javax.swing.table.TableModel对象,在开始前,我们先理解javax.swing.table.TableModel和JTable之间的关系:模特与衣服之间的关系:


  JTable对象---------->TableModel

 

     简单的说,JTable只是一个界面,主要负责显示功能,但JTable对象具体显示多少行多少列,甚示每行每列中显示什么类型的数据,JTable中的单元格是否可编辑,编辑之后怎么办…关于数据提供和数据操作的实现,都是由这个JTable对象的TableModel对象所负责的;反向而言,当JTable对象界面的数据被改动时,JTable会自动调用自己模型中的方法将改动反映到模型中。

  说了这么多,我们来看TableModel到底是什么东东----它是一个接口定义,源码说明如下:

//通过调用JTable对象的setModel方法,传入实现了TableModel接口类的对象

public interface TableModel{

    public int getRowCount();//决定表格上显示多少行

    public int getColumnCount();//表格上显示多少列

     //得到某一列的列名,columnIndex:列的序号,从0开始

    public String getColumnName(int columnIndex);

    //得到某一列的数据类型,columnIndex:列的序号,从0开始

    public Class<?> getColumnClass(int columnIndex);

//某一单元格在界面上是否可直接编辑,rowIndex:行号,columnIndex:列号,从0开始

    public boolean isCellEditable(int rowIndex, int columnIndex);

  //具体的JTable在显示时,调用这个方法取得每一个一单元格的值

   public Object getValueAt(int rowIndex, int columnIndex);

  //如果表格可编辑,表格对象将调用这个方法将改变后的值反映到它的model对象中  

   //aValue代表修改后的值,rowIndex,columnIndex表示所在的行列索引。

public void setValueAt(Object aValue, int rowIndex, int columnIndex);

     //模型对象可调用这个方法为自己加入一个监听器

    public void addTableModelListener(TableModelListener l);

     //移除模型对象中的监听器

    public void removeTableModelListener(TableModelListener l);

}

根据以上接口定义,我们只需要编写一个实现了TableModel的类,通过如下样例代码:javax.swing.JTable table=new javax.swing.JTable();

table.setModel(new 实现了TableModel接口的类);

   就可以在JTable对象在显示时,就会自动调用传入的Model中的方法用以填充自己的单元格的数据。

2.TableModel实践:

   首先,我们编写一个TableModel的实现类如下:

import javax.swing.event.TableModelListener;

/**自定义的tableModel实现类*/

public class MyTableModelV1  implements javax.swing.table.TableModel{

//多少行:

    public int getRowCount(){

     return 10;

    }

  //多少列

    public int getColumnCount(){

     return 5;

    }

//取得列名    

    public String getColumnName(int columnIndex){

     return " "+columnIndex+"列名";

    }

    //每一列的数据类型:我们这里显示的都是String

    public Class<?> getColumnClass(int columnIndex){

      return String.class;

    }

   //指定的单元格是否可从界面上编辑

    public boolean isCellEditable(int rowIndex, int columnIndex){

     if(columnIndex==0){

     return false;

     }

      return true;

    }

    //取得指定单元格的值

    public Object getValueAt(int rowIndex, int columnIndex){

     return rowIndex+"--"+columnIndex;

    }

   //从表格界面上改变了某个单元格的值后会调用这个方法

   public void setValueAt(Object aValue, int rowIndex, int columnIndex){

        String s="Change at: "+rowIndex+"--- "+columnIndex+" newValue: "+aValue;

        System.out.println(s);

    }

   //这两个接口方法暂无用

    public void addTableModelListener(TableModelListener l){}

    public void removeTableModelListener(TableModelListener l){}

}

使用这个TableModel对象的JTable将显示10行5列,每个单元格将返回getValueAt方法返回的字符串,当我们在使用它的表格界面上编辑表格数据(第一列不可编辑,Model中限定了),就会调用setValue方法将编辑过后的值打印出来。

   用以显示这个Model的Jtable和界面代码如下:

//TableModel应用测试

public class TestJTable {

//程序入口

public static void main(String[] args) {

javax.swing.JFrame jf=new javax.swing.JFrame("表格测试");

jf.setSize(300,400);

java.awt.FlowLayout fl=new java.awt.FlowLayout();

jf.setLayout(fl);

//1.创建一个默认的简单表格对像:

javax.swing.JTable table=new javax.swing.JTable();

//2.创建我们自定义的TableModel对象

MyTableModelV1    tm=new MyTableModelV1();

//3.将其设置为TableModel

table.setModel(tm);

jf.add(table);

jf.setDefaultCloseOperation(3);

jf.setVisible(true);

}

}

 要让某个JTable对象按照我们自己实现的TableModel显示数据,只需要创建我们实现的TableModel的对象:

MyTableModelV1    tm=new MyTableModelV1();

然后调用JTable对象的setModel方法,传入自定义的TableModel对象即可

3.使用JTable+TableModel展示java中的数据对象:

具体请看示例,将多个UserInfo对象列表的数据显示到JTable中,首先,我们需要编写自己的TableModel类,即实现了javax.swing.table.JtableModel接口的类,这个实现类使用装有UserInfo的List对象,负责将列表中的用户对象信息提供给Jtable对象显示:

import java.util.List;

import javax.swing.event.TableModelListener;

import javax.swing.table.TableModel;

/**

 * 用以在JTable中显示UserInfo对象的TableModel实现类

 * 

 */

public class UserInfoTableModel implements TableModel{

private List<UserInfo> userList; //要显示的UserInfo对象列表

      //创建模型对象时,必须传入要显示的UserInfo对象列表

  public UserInfoTableModel(List<UserInfo> userList){

   this.userList=userList;

  }

//得到行数:列表中有几个UserInfo对象,就显示几行

 public int getRowCount(){

 return userList.size();

 }

 //得到列数,UserInfo对象的每个属性是一列,id,name,age,3

 public int getColumnCount(){

 return 3;

 }

 //指定某列的类型:暂时都是字符串类型,

 public Class<?> getColumnClass(int columnIndex){

 return String.class;

 }

 //得到指定单元格的值:第几行,就是列表中的第几个UserInfo对象

 public Object getValueAt(int rowIndex, int columnIndex){

// 第几行,就是列表中的第几个UserInfo对象

           UserInfo user=userList.get(rowIndex);

        if(columnIndex==0){//第一列是UserInfo对象的id

         return ""+user.getId();

        }else if(columnIndex==1){//第二列是name属性值

         return user.getName();

        }else if(columnIndex==2){//第二列是age

         return ""+user.getAge();

        }else{//除非设计时逻辑错误,否则不会到这里

         return "出错!";

        }

     }

 //界面数据有变化时,模型对象的这个方法会被调用,暂时弹出说明框

 public void setValueAt(Object aValue, int rowIndex, int columnIndex){

String info=rowIndex+""+columnIndex+"列的值改变: "+aValue.toString();

 javax.swing.JOptionPane.showMessageDialog(null,info);

 }

 //指定某单元格是否可编辑:第一列不可编缉,第一列是ID,是每个对象的唯一识别号

 public boolean isCellEditable(int rowIndex, int columnIndex){

 if(columnIndex!=0){

 return true;

 }

 return false;

 }

 //取每一列的列名

 public String getColumnName(int columnIndex){

 if(columnIndex==0){//第一列是UserInfo对象的id

         return "序 号";

        }else if(columnIndex==1){//第二列是name属性值

         return "姓 名";

        }else if(columnIndex==2){//第二列是age

         return "年 令";

        }else{//除非设计时逻辑错误,否则不会到这里

         return "出错!";

        }

 }

 //添加和移除监听器的方法暂不用,写为空的

 public void addTableModelListener(TableModelListener l){}

public void removeTableModelListener(TableModelListener l){}

}

   接下来,我们创建界面和JTable对象,使用我们新编写的UserInfoTableModel对象显示用户数据。

/**

 * JTableTableModel使用示例 v1

 * 

 */

public class UserTableUIV1 {

     //程序入口

public static void main(String[] args) {

UserTableUIV1 lu=new UserTableUIV1();

lu.setupUI();

}

//显示主界面

public void setupUI(){

javax.swing.JFrame jf=new javax.swing.JFrame("JTable-TableModel示例");

jf.setSize(300,200);

java.awt.FlowLayout fl=new java.awt.FlowLayout();

jf.setLayout(fl);

//创建一个表格对象

final javax.swing.JTable table=new javax.swing.JTable();

//得到要显示的用户列表对象:

List<UserInfo> userList=getUserList();

//创建我们实现的TableModel对象,创建时要传入用户列表对象

UserInfoTableModel tm=new UserInfoTableModel(userList);

 table.setModel(tm);//将模型设给表格

    jf.add(table);

     jf.setDefaultCloseOperation(3);

 jf.setVisible(true);

}

//模拟生成用户对象列表

private List<UserInfo> getUserList(){

List<UserInfo> uList=new ArrayList();

for(int i=0;i<100;i++){

UserInfo user=new UserInfo();

user.setId(i+1);

user.setAge(20+i);

user.setName("用户"+i);

uList.add(user);

}

return uList;

}

}

关于JTable和TableModel对象,一定要体会的就是“衣服”和“模特”之间的关系,呵呵;当我们在界面上修改了JTable中的值,模型对象中的方法就会被调用。

 但这个JTable看起来一点也不漂亮,表格的标题头也没显示出来,接下来,我们美化一下,现在美化JTable,与模型,即数据模型没关系,就像要改衣服,不用动模特一样:

2.JTable展示方式的美化:

1.设置表格的宽度和高度:

如下代码示例:

//设每一列的宽度

 for(int i=0;i<table.getColumnCount();i++){

 table.getColumnModel().getColumn(i).setPreferredWidth(40); 

      }

 table.setRowHeight(20);//设定每一列的高度

2.要显示表头:

要将Jtable放到滚动板(javax.swing.JscrollPane)上,并设定其大小:

使用如下代码段,:

//将表格对象放到滚动面板对象上

 javax.swing.JScrollPane scrollPane = new JScrollPane(table);

 //设定表格在面板上的大小

table.setPreferredScrollableViewportSize(new Dimension(200, 70));

         //超出大小后,JScrollPane自动出现滚动条

  scrollPane.setAutoscrolls(true);

  jf.add(scrollPane);//scrollPane对象加到界面上

3.新加列,将列设为下拉框:

代码示例:

table.addColumn(new TableColumn(3));

  //创建下拉框对象,并设定其中的值

    JComboBox c = new JComboBox();

    c.addItem("长沙");

    c.addItem("株州");

    c.addItem("湘潭");

    c.setSelectedIndex(0);

//将下拉框设为表格的单元格:

table.getColumnModel().getColumn(3).setCellEditor(new DefaultCellEditor(c));

4.表格排序:

排序要实现的功能是,当单击表头时,所在列会自动排序,代码段如下:

RowSorter<javax.swing.table.TableModel> sorter = new TableRowSorter<TableModel>(table.getModel());

    table.setRowSorter(sorter);

3. JTable事件响应和项目设想

JTable事件响应是非常简单,如下代码片断所示,我们可以给表格加上一个鼠标事件监听器,当鼠标单击表格(上的某一个单元格)时,弹出单元格所在的行表和单元格中的值:

//table加上一个鼠标事件监听器对象

 table.addMouseListener(new java.awt.event.MouseAdapter(){

          public void mouseClicked(MouseEvent e) {//仅当鼠标单击时响应

          //得到选中的行列的索引值

         int r= table.getSelectedRow();

      int c=  table.getSelectedColumn();

          //得到选中的单元格的值,表格中都是字符串

      Object value= table.getValueAt(r, c);

   String info=r+""+c+"列 值 : "+value.toString();

   javax.swing.JOptionPane.showMessageDialog(null,info);

          }

         });

 

表格某个单元格的值被编辑后,当焦点移出时,表格会自动调用自己的模型的setValueAt方法,传入改变后的值和行列索引,这个功能也可被利用来做事件响应。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值