zoukankan      html  css  js  c++  java
  • JTable的应用(一)

    类层次结构图:
    java.lang.Object
    --java.awt.Component
    --java.awt.Container
    --javax.swing.JComponent
    --javax.swing.JTabel
    在使用JTable以前,我们先看一下它的构造函数有哪些, 以及应该如何使用:
    JTabel构造函数:
    JTable():建立一个新的JTables,并使用系统默认的Model.
    JTable(int numRows,int numColumns):建立一个具有numRows行,numColumns列的空表格,使用的是DefaultTableModel.
    JTable(Object[][] rowData,Object[][] columnNames):建立一个显示二维数组数据的表格,且可以显示列的名称。
    JTable(TableModel dm):建立一个JTable,有默认的字段模式以及选择模式,并设置数据模式。
    JTable(TableModel dm,TableColumnModel cm):建立一个JTable,设置数据模式与字段模式,并有默认的选择模式。
    JTable(TableModel dm,TableColumnModel cm,ListSelectionModel sm):建立一个JTable,设置数据模式、字段模式、与选择模式。
    JTable(Vector rowData,Vector columnNames):建立一个以Vector为输入来源的数据表格,可显示行的名称。
    我们先以Array构造方式,说明如何利用JTable来建立一个简单的表格:

    复制代码
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;

    public class SimpleTable{
    public SimpleTable(){
         JFrame f=new JFrame();
         Object[][] playerInfo={
                     {"阿呆",new Integer(66),new Integer(32),new Integer(98),new Boolean(false)},
                    {"阿呆",new Integer(82),new Integer(69),new Integer(128),new Boolean(true)},
        };
        String[] Names={"姓名","语文","数学","总分","及格"};
        JTable table=new JTable(playerInfo,Names);
        table.setPreferredScrollableViewportSize(new Dimension(550,30));
        JScrollPane scrollPane=new JScrollPane(table);
        f.getContentPane().add(scrollPane,BorderLayout.CENTER);
        f.setTitle("Simple Table");
        f.pack();
        f.show();

        f.addWindowListener(new WindowAdapter() {
                            public void windowClosing(WindowEvent e) {
                              System.exit(0);
                            }
                          });
       }
       public static void main(String[] args){
         SimpleTable b=new SimpleTable();
       }
      }
    复制代码

      表格由两部份组成:分别是行标题(Column Header)与行对象(Column Object).利用JTable所提供的getTableHeader()方法取得行标题。在这个例子中,我们将JTable放在 JScrollPane中,这种做法可以将Column Header与Colmn Object完整的显示出来,因为JScrollPane会自动取得Column Header.但如果文坛读者将上面第15行去掉并修改第16行:f.getContentPane().add(table,BorderLayout.CENTER); 则运行结果你会发现Column Header不见了。
      如果你不想用JScrollPane,要解决这个问题,你必须将程序修改如下:
    JTable table=new JTable(p,n);
    table.setPreferredScrollableViewportSize(new Dimension(550,30));
    f.getContentPane().add(table.getTableHeader(),BorderLayout.NORTH);
    f.getContentPane().add(table,BorderLayout.CENTER);
      运行结果就会跟之前一样有行标题了.上面的运行结果就会跟发现,每个字段的宽度都是一样的,除非你自行拉曳某个列宽。若我们想一开始就设置列宽的值,可以 利用TableColumn类所提供的setPreferredWidth()方法来设置,并可利用JTable类所提供的 setAutoResizeMode()方法来设置调整某个列宽时其他列宽的变化情况,我们看下面这个例子:

    复制代码
    import javax.swing.*;
    import javax.swing.table.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    public class SimpleTable2{
    public SimpleTable2(){
        JFrame f=new JFrame();
        Object[][] p={
          {"阿呆",new Integer(66),new Integer(32),new Integer(98),new Boolean(false),new Boolean(false)},
          {"阿呆",new Integer(82),new Integer(69),new Integer(128),new Boolean(true),new Boolean(false)},
        };
        String[] n={"姓名","语文","数学","总分","及格","作弊"};
        TableColumn column=null;
        JTable table=new JTable(p,n);
        table.setPreferredScrollableViewportSize(new Dimension(550,30));
        table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
        //利用JTable中的getColumnModel()方法取得TableColumnModel对象;再利用TableColumnModel界面 所定义的getColumn()方法取TableColumn对象,利用此对象的setPreferredWidth()方法就可以控制字段的宽度.
        for (int i=0;i<6;i++){
          column=table.getColumnModel().getColumn(i);
          if ((i%2)==0) column.setPreferredWidth(150);
          else column.setPreferredWidth(50);
        }
        JScrollPane scrollPane=new JScrollPane(table);
        f.getContentPane().add(scrollPane,BorderLayout.CENTER);
        f.setTitle("Simple Table");
        f.pack();
        f.show();
        f.setVisible(true);
        f.addWindowListener(new WindowAdapter() {
                            public void windowClosing(WindowEvent e) {
                              System.exit(0);
                            }
                          });  
        }
    public static void main(String[] args){
        new SimpleTable2();
    }
    }
    复制代码


    列可调整的5个参数:
    AUTO_RESIZE_SUBSEQUENT_COLUMENS:当调整某一列宽时,此字段之后的所有字段列宽都会跟着一起变动。此为系统默认值。
    AUTO_RESIZE_ALL_COLUMNS:当调整某一列宽时,此表格上所有字段的列宽都会跟着一起变动。
    AUTO_RESIZE_OFF:当调整某一列宽时,此表格上所有字段列宽都不会跟着改变。
    AUTO_RESIZE_NEXT_COLUMN:当调整某一列宽时,此字段的下一个字段的列宽会跟着改变,其余均不会变。
    AUTO_RESIZE_LAST_COLUMN:当调整某一列宽时,最后一个字段的列宽会跟着改变,其余均不会改变。
      由以上范例可知,利用Swing来构造一个表格其实很简单的,只要你利用Vector或Array来作为我们表格的数据输入,将Vector或Array 的内容填入JTable中,一个基本的表格就产生了。不过,虽然利用JTable(Object[][] rowData,Object[][] columnNames)以及JTable(Vector rowData,Vector columnNames)构造函数来构造构造JTable很方便,但却有些缺点。例如上例中,我们表格中的每个字段(cell)一开始都是默认为可修改 的,用户因此可能修改到我们的数据;其次,表格中每个单元(cell)中的数据类型将会被视为同一种。在我们的例子中,数据类型皆被显示为String的 类型,因此,原来的数据类型声明为Boolean的数据会以String的形式出现而不是以检查框(Check Box)出现。除此之外,如果我们所要显示的数据是不固定的,或是随情况而变,例如同样是一份成绩单,老师与学生所看到的表格就不会一样,显示的外观或操 作模式也许也不相同。为了因应这些种种复杂情况,上面简单的构造方式已不宜使用Swing提供各种Model(如:TableModel、 TableColumnModel与ListSelectionModel)来解决上述的不便,以增加我们设计表格的弹性。我们下面就先对 TableModel来做介绍:

    8-2:TableModel

      TableModel类本身是一个interface,在这个interface里面定义了若干的方法:包括了存取表格字段(cell)的内容、计算表格 的列数等等的基本存取操作,让设计者可以简单地利用TableModel来实作他所想要的表格。TableModel界面是放在 javax.swing.table package中,这个package定义了许多JTable会用到的各种Model,读者可利用java api文件找到这个package,并由此package找到各类或界面所定义的方法。
    TableModel方法:
      void addTableModelListener(TableModelListener l):使表格具有处理TableModelEvent的能力。当表格的Table Model有所变化时,会发出TableModel Event事件信息.
      Class getColumnClass(int columnIndex):返回字段数据类型的类名称.
      int getColumnCount():返回字段(行)数量.
      String getColumnName(int columnIndex):返回字段名称.
      int getRowCount():返回数据列数量.
      Object getValueAt(int rowIndex,int columnIndex):返回数据某个cell中的值.
      boolean isCellEditable(int rowIndex,int columnIndex):返回cell是否可编辑,true的话为可编辑.
      void removeTableModelListener(TableModelListener l):从TableModelListener中移除一个listener.
      void setValueAt(Object aValue,int rowIndex,int columnIndex):设置某个cell(rowIndex,columnIndex)的值;

      由于TableModel本身是一个Interface,因此若要直接实现此界面来建立表格并不是件轻松的事.幸好java提供了两个类分别实现了 这个界面,一个是AbstractTableModel抽象类,一个是DefaultTableModel实体类.前者实现了大部份的 TableModel方法,让用户可以很有弹性地构造自己的表格模式;后者继承前者类,是java默认的表格模式.这三者的关系如下所示:
    TableModel---implements--->AbstractTableModel-----extends--->DefaultTableModel

    8-3:AbstractTableModel:

      java提供的AbstractTableModel是一个抽象类,这个类帮我们实现大部份的TableModel方法,除了 getRowCount(),getColumnCount(),getValueAt()这三个方法外.因此我们的主要任务就是去实现这三个方法.利用 这个抽象类就可以设计出不同格式的表格.我们来看看它所提供的方法.
    AbstractTableModel方法:
      void addTableModelListener(TableModelListener l):使表格具有处理TableModelEvent的能力.当表格的Table Model有所变化时,会发出TableModelEvent事件信息.       int  findColumn(String columnName):寻找在行名称中是否含有columnName这个项目.若有,则返回其所在行的位置;反之则返回-1表示未找到.
      void fireTableCellUpdated(int row, int column):通知所有的Listener在这个表格中的(row,column)字段的内容已经改变了.
      void fireTableChanged(TableModelEvent e):将所收的事件通知传送给所有在这个table model中注册过的TableModelListeners.
      void fireTableDataChanged():通知所有的listener在这个表格中列的内容已经改变了.列的数目可能已经改变了,因此JTable可能需要重新显示此表格的结构.
      void fireTableRowsDeleted(int firstRow, int lastRow):通知所有的listener在这个表格中第firstrow行至lastrow列已经被删除了.
      void fireTableRowsUpdated(int firstRow, int lastRow):通知所有的listener在这个表格中第firstrow行至lastrow列已经被修改了.
      void fireTableRowsInserted(int firstRow, int lastRow):通知所有的listener在这个表格中第firstrow行至lastrow列已经被加入了.
      void fireTableStructureChanged():通知所有的listener在这个表格的结构已经改变了.行的数目,名称以及数据类型都可能已经改变了.
      Class getColumnClass(int columnIndex):返回字段数据类型的类名称.
      String getColumnName(int column):若没有设置列标题则返回默认值,依次为A,B,C,...Z,AA,AB,..;若无此column,则返回一个空的String. 
      Public EventListener[] getListeners(Class listenerType):返回所有在这个table model所建立的listener中符合listenerType的listener,并以数组形式返回.
      boolean isCellEditable(int rowIndex, int columnIndex):返回所有在这个table model所建立的listener中符合listenerType形式的listener,并以数组形式返回.
      void removeTableModelListener(TableModelListener l):从TableModelListener中移除一个listener.
      void setValueAt(Object aValue, int rowIndex, int columnIndex):设置某个cell(rowIndex,columnIndex)的值.
      若你仔细比较TableModel所定义的方法与上述AbstractTableModel所提供的方法,你可以发 现,AbstractTableModel抽象类并没有实现getRowCount(),getColumnCount(),getValueAt()这 三个方法,这也就是为什么我们要去实现这三个方法的原因.下面我们来看如何使用AbstractTableModel来实作出自己想要的表格模式.
    范例:TableModel1.java

    View Code import javax.swing.table.AbstractTableModel;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    public class TableModel1{
    public TableModel1() {
        JFrame f = new JFrame();
        MyTable mt=new MyTable();
        JTable t=new JTable(mt);
        t.setPreferredScrollableViewportSize(new Dimension(550, 30));
        JScrollPane s = new JScrollPane(t);
        f.getContentPane().add(s, BorderLayout.CENTER);
        f.setTitle("JTable1");
        f.pack();
        f.setVisible(true);
        f.addWindowListener(new WindowAdapter() {
                            public void windowClosing(WindowEvent e) {
                              System.exit(0);
                            }
                          });
    }
    public static void main(String args[]) {
        new TableModel1();
    }
    }
    class MyTable extends AbstractTableModel{
    Object[][] p = {
        {"阿呆", new Integer(66), new Integer(32), new Integer(98), new Boolean(false),new Boolean(false)},
        {"阿瓜", new Integer(85), new Integer(69), new Integer(154), new Boolean(true),new Boolean(false)},
    };
    String[] n = {"姓名", "语文","数学","总分","及格","作弊"};
    public int getColumnCount() {
        return n.length;
    }
    public int getRowCount() {
        return p.length;
    }
    public String getColumnName(int col) {
        return n[col];
    }
    public Object getValueAt(int row, int col) {
        return p[row][col];
    }
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }
    }
    上例中表格内的数据类型不论是String,int或是Boolean类型,都均以string的类型显示.例如在及格的字段中,原本的数据是以 Boolean类型来表示,但显示在JTable上时便转换成字符串形式,若想要使表格能显示出不同的数据类型,我们要在MyTable中 Override写getColumnClass()方法,这个方法可以让我们分辨出表格中每一行的数据类型,并将此类型作适当的显示:
    public Class getColumnClass(int c) {
    return getValueAt(0, c).getClass();
    }
    

      

    这样"作弊"会以Check Box显示,数据类型一律靠右显示,String类型一律靠左显示.
    TableModel2.java

    View Code import javax.swing.table.AbstractTableModel;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    public class TableModel1{
    public TableModel1() {
        JFrame f = new JFrame();
        MyTable mt=new MyTable();
        JTable t=new JTable(mt);
        t.setPreferredScrollableViewportSize(new Dimension(550, 30));
        JScrollPane s = new JScrollPane(t);
        f.getContentPane().add(s, BorderLayout.CENTER);
        f.setTitle("JTable1");
        f.pack();
        f.setVisible(true);
        f.addWindowListener(new WindowAdapter() {
                            public void windowClosing(WindowEvent e) {
                              System.exit(0);
                            }
                          });
    }
    public static void main(String args[]) {
        new TableModel1();
    }
    }
    class MyTable extends AbstractTableModel{
    Object[][] p = {
        {"阿呆", new Integer(66), new Integer(32), new Integer(98), new Boolean(false),new Boolean(false)},
        {"阿瓜", new Integer(85), new Integer(69), new Integer(154), new Boolean(true),new Boolean(false)},
    };
    String[] n = {"姓名", "语文","数学","总分","及格","作弊"};
    public int getColumnCount() {
        return n.length;
    }
    public int getRowCount() {
        return p.length;
    }
    public String getColumnName(int col) {
        return n[col];
    }
    public Object getValueAt(int row, int col) {
        return p[row][col];
    }
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }
    }
    上例中表格内的数据类型不论是String,int或是Boolean类型,都均以string的类型显示.例如在及格的字段中,原本的数据是以 Boolean类型来表示,但显示在JTable上时便转换成字符串形式,若想要使表格能显示出不同的数据类型,我们要在MyTable中 Override写getColumnClass()方法,这个方法可以让我们分辨出表格中每一行的数据类型,并将此类型作适当的显示:
    public Class getColumnClass(int c) {
    return getValueAt(0, c).getClass();
    }
    

      

    8-4:TableColumnModel:

    TableColumnModel本身是一个Interface,里面定义了许多与表格的"列(行)"有关的方法,例如增加列,删除列,设置与取得"列" 的相关信息.通常我们不会直接实现TableColumnModel界面,而是会利用JTable的getColumnModel()方法取得 TableColumnModel对象,再利用此对象对字段做设置.举例来说,如果我们想设计的表格是包括有下拉式列表的Combo Box,我们就能利用TableColumnModel来达到这样的效果.我们先看看下面的例子:

    View Code import javax.swing.table.AbstractTableModel;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    public class TableModel1{
    public TableModel1() {
        JFrame f = new JFrame();
        MyTable mt=new MyTable();
        JTable t=new JTable(mt);
        t.setPreferredScrollableViewportSize(new Dimension(550, 30));
        JScrollPane s = new JScrollPane(t);
        f.getContentPane().add(s, BorderLayout.CENTER);
        f.setTitle("JTable1");
        f.pack();
        f.setVisible(true);
        f.addWindowListener(new WindowAdapter() {
                            public void windowClosing(WindowEvent e) {
                              System.exit(0);
                            }
                          });
    }
    public static void main(String args[]) {
        new TableModel1();
    }
    }
    class MyTable extends AbstractTableModel{
    Object[][] p = {
        {"阿呆", new Integer(66), new Integer(32), new Integer(98), new Boolean(false),new Boolean(false)},
        {"阿瓜", new Integer(85), new Integer(69), new Integer(154), new Boolean(true),new Boolean(false)},
    };
    String[] n = {"姓名", "语文","数学","总分","及格","作弊"};
    public int getColumnCount() {
        return n.length;
    }
    public int getRowCount() {
        return p.length;
    }
    public String getColumnName(int col) {
        return n[col];
    }
    public Object getValueAt(int row, int col) {
        return p[row][col];
    }
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }
    }
    上例中表格内的数据类型不论是String,int或是Boolean类型,都均以string的类型显示.例如在及格的字段中,原本的数据是以 Boolean类型来表示,但显示在JTable上时便转换成字符串形式,若想要使表格能显示出不同的数据类型,我们要在MyTable中 Override写getColumnClass()方法,这个方法可以让我们分辨出表格中每一行的数据类型,并将此类型作适当的显示:
    public Class getColumnClass(int c) {
    return getValueAt(0, c).getClass();
    }
    

      

         读者运行此程序可以发现,利用继承AbstractTableModel抽象类所产生的JTable的内容是不能被修改的.那如果想要让用户可以修改表格 中的某一个字段,例如勾选Check Box或是直接修改某个字段的数字,该怎么做呢?很简单,只要我们在范例中的MyTable类中覆写AbstractTableModel抽象类中的 isCellEditable()方法即可.下面即是isCellEditable()的实作:
    public boolean isCellEditable(int rowIndex,int columnIndex){
    return true;
    }
    在isCellEditable()中,我们只有一行简单的程序代码:return true,意思是将我们表格内的每个cell都变成可修改.但仅仅修改这个程序代码还不行,你可以发现虽然表格现在变成了可以修改了,但更改完之后按下 Enter 键,内容马上恢复成原有的值!解决的方法是覆写AbstractTableModel抽象类中的setValueAt()方法,这个方法主要是让我们将改 过的值存入表格中,如下所示:
    public void setValueAt(Object value,int row,int col){
    p[row][col]=value;
    fireTableCellUpdated(row,col);
    }
    其中value为我们所更改的值,我们将value存入p[row][col]中,并且调用firTableCellUpdated()函数来告诉我们的 系统表格已经做了更改了,关于这一部份,我们后面会再对事件处理作详细地介绍,在此范例中有没有加入fireTableCellUpdated()方法对 运行结果不会造成影响.

    8-5:SelectionModel

    表格的选择模式是依据我们前面所讲的ListSelectionModel而来,因此它的操作模式与事件处理跟JList没什么分别!我们稍微复习一下ListSelectionModel这个Interface,它包含了3个常数值,如下:
    static int SINGLE_SELECTION
    static int SINGLE_INTERVAL_SELECTION
    static int MULTIPLE_INTERVAL_SELECTION
    分别可让用户作单一选择,连续区间选择与多重选择.当用户作后面两个模式的操作时,应配合 Shift 键或 Ctrl 键.要使用ListSelectionModel可利用JTable的getSelectionModel()方法取得 ListSelectionModel对象,再利用ListSelectionModel界面所定义的setSelectionModel()来设置选择 模式.如同JList一般,当用户对表格作数据域位的选取时会产生ListSelectionEvent事件,要处理这个事件就必须实现 ListSelectionListener这个界面,此界面定义了一个方法,那就是valueChanged().我们来看下面的例子,用户可在按钮上 选择哪种选择模式,当用户选取表格数据时,程序会将用户选取的数据显示在表格下面的JLabel中.

    SelectionModelDemo.java

    View Code import javax.swing.table.AbstractTableModel;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    public class TableModel1{
    public TableModel1() {
        JFrame f = new JFrame();
        MyTable mt=new MyTable();
        JTable t=new JTable(mt);
        t.setPreferredScrollableViewportSize(new Dimension(550, 30));
        JScrollPane s = new JScrollPane(t);
        f.getContentPane().add(s, BorderLayout.CENTER);
        f.setTitle("JTable1");
        f.pack();
        f.setVisible(true);
        f.addWindowListener(new WindowAdapter() {
                            public void windowClosing(WindowEvent e) {
                              System.exit(0);
                            }
                          });
    }
    public static void main(String args[]) {
        new TableModel1();
    }
    }
    class MyTable extends AbstractTableModel{
    Object[][] p = {
        {"阿呆", new Integer(66), new Integer(32), new Integer(98), new Boolean(false),new Boolean(false)},
        {"阿瓜", new Integer(85), new Integer(69), new Integer(154), new Boolean(true),new Boolean(false)},
    };
    String[] n = {"姓名", "语文","数学","总分","及格","作弊"};
    public int getColumnCount() {
        return n.length;
    }
    public int getRowCount() {
        return p.length;
    }
    public String getColumnName(int col) {
        return n[col];
    }
    public Object getValueAt(int row, int col) {
        return p[row][col];
    }
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }
    }
    上例中表格内的数据类型不论是String,int或是Boolean类型,都均以string的类型显示.例如在及格的字段中,原本的数据是以 Boolean类型来表示,但显示在JTable上时便转换成字符串形式,若想要使表格能显示出不同的数据类型,我们要在MyTable中 Override写getColumnClass()方法,这个方法可以让我们分辨出表格中每一行的数据类型,并将此类型作适当的显示:
    public Class getColumnClass(int c) {
    return getValueAt(0, c).getClass();
    }

          说明:在此范例中,我们要处理ActionEvent与ListSelectionEvent,因此在程序中我们要实现ActionListenrer与 ListSelectionListener界面,而ListSelectionEvent是属于Swing事件,因此程序中我们要import javax.swing.event package进来.

    8-6:DefaultTableModel

    我们曾提到过DefaultTableModel类,并说明了此类是继承AbstractTableModel抽象类而来,且实现了 getColumnCount(),getRowCount()与getValueAt()3个方法.因此在实际的使用 上,DefaultTableModel比AbstractTableModel要来得简单许多,也较常被拿来使用.DefaultTableModel 内部使用Vector来使用表格的数据,若佻所要显示的表格格式是比较单纯的变化,笔者建议使用DefaultTableModel类会来得方便也简单许 多.若佻所要显示的数据模式非常复杂,例如我们所举的成绩表格外加学生选课信息等,像这类的表格通常显示的信息会因人面异,因此使用 AbstractTableModel会比较容易设计些.

    下面是DefaultTableModel的构造函数:
    DefaultTableModel():建立一个DefaultTableModel,里面没有任何数据.
    DefaultTableModel(int numRows,int numColumns):建立一个指定行列数的DefaultTableModel.
    DefaultTableModel(Object[][] data,Object[] columnNames):建立一个DefaultTableModel,输入数据格式为Object Array.系统会自动调用setDataVector()方法来设置数据。
    DefaultTableModel(Object[] columnNames,int numRows):建立一个DefaultTableModel,并具有Column Header名称与行数信息。
    DefaultTableModel(Vector columnNames,int numRows):建立一个DefaultTableModel,并具有column Header名称与行数信息。
    DefaultTableModel(Vector data,Vector columnNames):建立一个DefaultTableModel,输入数据格式为Vector.系统会自动调用setDataVector()方法来设置数据。
    DefaultTableModel类提供相当多好用的方法,如之前我们谈论过的 getColumnCount(),getRowCount(),getValueAt(),isCellEditable(),setValueAt() 等方法,均可直接使用。且DefaultTableModel也提供了addColumn()与addRow()等方法,可让我们随时增加表格的数据。下 面我们就举一个动态增加表格字段的例子:

    import java.awt.*;
    import java.awt.event.*;
    import java.util.Vector;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.table.*;
    
    public class AddRemoveCells implements ActionListener{
    JTable table = null;
    DefaultTableModel defaultModel = null;
    public AddRemoveCells(){
        JFrame f = new JFrame();
        String[] name = {"字段 1","字段 2","字段 3","字段 4","字段 5"};
        String[][] data = new String[5][5];
        int value =1;
        for(int i=0; i<data.length; i++){
          for(int j=0; j<data.length ; j++)
          data[j] = String.valueOf(value++);
        }
    
        defaultModel = new DefaultTableModel(data,name);
        table=new JTable(defaultModel);
        table.setPreferredScrollableViewportSize(new Dimension(400, 80));
        JScrollPane s = new JScrollPane(table);
    
        JPanel panel = new JPanel();
        JButton b = new JButton("增加行");
        panel.add(b);
        b.addActionListener(this);
        b = new JButton("增加列");
        panel.add(b);
        b.addActionListener(this);
        b = new JButton("删除行");
        panel.add(b);
        b.addActionListener(this);
        b = new JButton("删除列");
        panel.add(b);
        b.addActionListener(this);
    
        Container contentPane = f.getContentPane();
        contentPane.add(panel, BorderLayout.NORTH);
        contentPane.add(s, BorderLayout.CENTER);
    
        f.setTitle("AddRemoveCells");
        f.pack();
        f.setVisible(true);
    
        f.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            System.exit(0);
          }
        });
    }
    /*要删除列必须使用TableColumnModel界面定义的removeColumn()方法。因此我闪先由JTable类的 getColumnModel()方法取得TableColumnModel对象,再由TableColumnModel的getColumn()方法取 得要删除列的TableColumn.此TableColumn对象当作是removeColumn()的参数。删除此列完毕后必须重新设置列数,也就是 使用DefaultTableModel的setColumnCount()方法来设置。*/
    public void actionPerformed(ActionEvent e){
        if(e.getActionCommand().equals("增加列"))    defaultModel.addColumn("增加列");
        if(e.getActionCommand().equals("增加行"))    defaultModel.addRow(new Vector());
        if(e.getActionCommand().equals("删除列")){
          int columncount = defaultModel.getColumnCount()-1;
          if(columncount >= 0) {    //若columncount<0代表已经没有任何列了。
            TableColumnModel columnModel = table.getColumnModel();
            TableColumn tableColumn = columnModel.getColumn(columncount);
            columnModel.removeColumn(tableColumn);
            defaultModel.setColumnCount(columncount);
          }
        }
        if(e.getActionCommand().equals("删除行")){
          int rowcount = defaultModel.getRowCount()-1;//getRowCount返回行数,rowcount<0代表已经没有任何行了。
          if(rowcount >= 0){
            defaultModel.removeRow(rowcount);
            defaultModel.setRowCount(rowcount);
    /*删除行比较简单,只要用DefaultTableModel的removeRow()方法即可。//删除行完毕后必须重新设置列数,也就是使用DefaultTableModel的setRowCount()方法来设置。*/
          }
        }
        table.revalidate();
    }
    
    public static void main(String args[]) {
        new AddRemoveCells();
    }
    }
    

      

  • 相关阅读:
    PAT A1094 The Largest Generation (25 分)——树的bfs遍历
    PAT A1055 The World's Richest (25 分)——排序
    PAT A1052 Linked List Sorting (25 分)——链表,排序
    PAT A1076 Forwards on Weibo (30 分)——图的bfs
    辅导员
    辅导员面试
    C程序设计
    Excel VBA 基本概念
    Excel函数
    导入excel表的数据到数据库ssh
  • 原文地址:https://www.cnblogs.com/renyuan/p/2724529.html
Copyright © 2011-2022 走看看