隨筆 - 45, 文章 - 6, 評論 - 4, 引用 - 0
          數(shù)據(jù)加載中……

          如何用java應(yīng)用程序創(chuàng)建表格

          多少有點(diǎn)麻煩
          JTable 組件:
          類層次結(jié)構(gòu)圖:
          java.lang.Object
          --java.awt.Component
          --java.awt.Container
          --javax.swing.JComponent
          --javax.swing.JTabel

          在使用 JTable 以前,我們先看一下它的構(gòu)造函數(shù)有哪些, 以及應(yīng)該如何使用:

          JTabel 構(gòu)造函數(shù):
          JTable():建立一個新的 JTables,并使用系統(tǒng)默認(rèn)的 Model.
          JTable(int numRows,int numColumns):建立一個具有 numRows 行,numColumns 列的空表格,
          使用的是 DefaultTableModel.
          JTable(Object[ ][ ] rowData,Object[ ][ ] columnNames):建立一個顯示二維數(shù)組數(shù)據(jù)的表格,且可
          以顯示列的名稱。
          JTable(TableModeldm):建立一個 JTable,有默認(rèn)的字段模式以及選擇模式,并設(shè)置數(shù)據(jù)模式。
          JTable(TableModeldm,TableColumnModel cm):建立一個 JTable,設(shè)置數(shù)據(jù)模式與字段模式,并
          有默認(rèn)的選擇模式。
          JTable(TableModel dm,TableColumnModel cm,ListSelectionModel sm):建立一個 JTable,設(shè)置數(shù)
          據(jù)模式、字段模式、與選擇模式。
          JTable(Vector rowData,Vector columnNames):建立一個以 Vector 為輸入來源的數(shù)據(jù)表格,可顯
          示行的名稱。


          我們先以 Array 構(gòu)造方式,說明如何利用 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={"姓名","語文","數(shù)學(xué)","總分","及格"};
             JTable table=new JTable(playerInfo,Names);
             table.setPreferredScrollableViewportSize(new Dimension(550,30)); //設(shè)置此表視口的首選大小
             JScrollPane scrollPane=new JScrollPane(table);
             f.getContentPane().add(scrollPane,BorderLayout.CENTER); //JFrame中僅包含一個JRootPane子容器。在   //JFrame中顯示的所有非菜單組件均應(yīng)該包含在JRootPane所提供的Content pane中因此frame.add(child);是錯誤的
             f.setTitle("SimpleTable");
             f.pack();
             f.show();
             app.addWindowListener
             (
                new WindowAdapter()
                {
                          public void windowClosing(WindowEvent e)
                          {
                          System.exit(0);
                          }
                }
             );
          }
          public static void main(String[] args)
          {
              SimpleTable b=new SimpleTable();
          }
          }
          運(yùn)行結(jié)果:


          由以上范例可知,利用 Swing 來構(gòu)造一個表格其實(shí)很簡單的,只要你利用 Vector 或 Array
          來作為我們表格的數(shù)據(jù)輸入,將 Vector 或 Array 的
          內(nèi)容填入 JTable 中,一個基本的表格就產(chǎn)生了。不過,雖然利用 JTable(Object[][]
          rowData,Object[][] columnNames)以及
          JTable(Vector rowData,Vector columnNames)構(gòu)造函數(shù)來構(gòu)造構(gòu)造 JTable 很方便,但卻有些缺
          點(diǎn)。例如上例中,我們表格中的每個字段
          (cell)一開始都是默認(rèn)為可修改的,用戶因此可能修改到我們的數(shù)據(jù);其次,表格中每個單元
          (cell)中的數(shù)據(jù)類型將會被視為同一種。在我
          們的例子中,數(shù)據(jù)類型皆被顯示為 String 的類型,因此,原來的數(shù)據(jù)類型聲明為 Boolean 的
          數(shù)據(jù)會以 String 的形式出現(xiàn)而不是以檢查框(
          Check Box)出現(xiàn)。
          除此之外,如果我們所要顯示的數(shù)據(jù)是不固定的,或是隨情況而變,例如同樣是一份成績
          單,老師與學(xué)生所看到的表格就不會一樣,顯
          示的外觀或操作模式也許也不相同。為了因應(yīng)這些種種復(fù)雜情況,上面簡單的構(gòu)造方式已不
          宜使用,Swing 提供各種 Model(如:
          TableModel、TableColumnModel 與 ListSelectionModel)來解決上述的不便,以增加我們設(shè)計(jì)
          表格的彈性。我們下面就先對 TableModel 來
          做介紹:


          TableModel

          TableModel類本身是一個interface,在這個interface里面定義了若干的方法:包括了存取表
          格字段(cell)的內(nèi)容、計(jì)算表格的列數(shù)等等的基本存取操作,讓設(shè)計(jì)者可以簡單地利用
          TableModel 來實(shí)作他所想要的表格。TableModel 界面是放在 javax.swing.table package 中,
          這個 package 定義了許多 JTable 會用到的各種 Model,讀者可利用 java api 文件找到這個
          package,并由此 package 找到各類或界面所定義的方法。


          TableModel 方法:
          void addTableModelListener(TableModelListener l):使表格具有處理 TableModelEvent 的能
          力。當(dāng)表格的 Table Model 有所變化時,會發(fā)出 TableModel Event 事件信息.
          Class getColumnClass(int columnIndex):返回字段數(shù)據(jù)類型的類名稱.

          int getColumnCount():返回字段(行)數(shù)量.
          String getColumnName(int columnIndex):返回字段名稱.
          int getRowCount():返回?cái)?shù)據(jù)列數(shù)量.
          Object getValueAt(int rowIndex,int columnIndex):返回?cái)?shù)據(jù)某個 cell 中的值.
          boolean isCellEditable(int rowIndex,int columnIndex):返回cell是否可編輯,true的話
          為可編輯.
          void removeTableModelListener(TableModelListener l):從 TableModelListener 中
          移除一個 listener.
          void setValueAt(Object aValue,int rowIndex,int columnIndex): 設(shè) 置 某 個
          cell(rowIndex,columnIndex)的值;


          由于TableModel本身是一個Interface,因此若要直接實(shí)現(xiàn)此界面來建立表格并不是件輕松
          的事.幸好 java 提供了兩個類分別實(shí)現(xiàn)了這個界面,一個是 AbstractTableModel 抽象類,一個是
          DefaultTableModel 實(shí)體類.前者實(shí)現(xiàn)了大部份的 TableModel 方法,讓用戶可以很有彈性地構(gòu)
          造自己的表格模式;后者繼承前者類,是 java 默認(rèn)的表格模式.這三者的關(guān)系如下所示:
          TableModel---implements--->AbstractTableModel-----extends--->DefaultTableModel


          AbstractTableModel:


          java 提供的 AbstractTableModel 是一個抽象類,這個類幫我們實(shí)現(xiàn)大部份的 TableModel 方
          法,除了 getRowCount(),getColumnCount(),getValueAt()這三個方法外.因此我們的主要任務(wù)就
          是去實(shí)現(xiàn)這三個方法.利用這個抽象類就可以設(shè)計(jì)出不同格式的表格.我們來看看它所
          提供的方法:
          AbstractTableModel 方法:
          void addTableModelListener(TableModelListener l):使表格具有處理 TableModelEvent 的能
          力.當(dāng)表格的 Table Model 有所變化時,會發(fā)出 TableModelEvent 事件信息.
          int findColumn(String columnName):尋找在行名稱中是否含有 columnName 這個項(xiàng)目.若
          有,則返回其所在行的位置;反之則返回-1 表示


          void fireTableCellUpdated(int row, int column):通知所有的 Listener 在這個表格中的
          (row,column)字段的內(nèi)容已經(jīng)改變了.
          void fireTableChanged(TableModelEvent e):將所收的事件通知傳送給所有在這個 table
          model 中注冊過的 TableModelListeners.
          void fireTableDataChanged():通知所有的 listener 在這個表格中列的內(nèi)容已經(jīng)改變了.列的
          數(shù)目可能已經(jīng)改變了,因此 JTable 可能需要重新顯示此表格的結(jié)構(gòu).
          void fireTableRowsDeleted(int firstRow, int lastRow):通知所有的 listener 在這個表格中第
          firstrow 行至 lastrow 列已經(jīng)被刪除了.
          void fireTableRowsUpdated(int firstRow, int lastRow):通知所有的 listener 在這個表格中第
          firstrow 行至 lastrow 列已經(jīng)被修改了.
          void fireTableRowsInserted(int firstRow, int lastRow):通知所有的 listener 在這個表格中第
          firstrow 行至 lastrow 列已經(jīng)被加入了
          .

          void fireTableStructureChanged():通知所有的listener在這個表格的結(jié)構(gòu)已經(jīng)改變了.行的數(shù)
          目,名稱以及數(shù)據(jù)類型都可能已經(jīng)改變了
          .
          Class getColumnClass(int columnIndex):返回字段數(shù)據(jù)類型的類名稱.
          String getColumnName(int column): 若 沒 有 設(shè) 置 列 標(biāo) 題 則 返 回 默 認(rèn) 值 , 依 次 為
          A,B,C,...Z,AA,AB,..;若無此 column,則返回一個空的 String
          .
          Public EventListener[] getListeners(Class listenerType):返回所有在這個 table model 所建立的
          listener 中符合 listenerType 的 listener,并以數(shù)組形式返回.
          boolean isCellEditable(int rowIndex, int columnIndex):返回所有在這個 table model 所建立的
          listener 中符合 listenerType 形式的 listener,并以數(shù)組形式返回.
          voidremoveTableModelListener(TableModelListener l):從 TableModelListener 中移除一個
          listener.
          voidsetValueAt(Object aValue, int rowIndex, int columnIndex)
          :設(shè)置某個 cell(rowIndex,columnIndex)的值.
          若你仔細(xì)比較TableModel所定義的方法與上述AbstractTableModel所提供的方法,你可以發(fā)
          現(xiàn),AbstractTableModel 抽象類并沒有實(shí)現(xiàn)
          getRowCount(),getColumnCount(),getValueAt()這三個方法,這也就是為什么我們要去實(shí)現(xiàn)這
          三個方法的原因.下面我們來看如何使用
          AbstractTableModel 來實(shí)作出自己想要的表格模式.


          范例:TableModel1.java


          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 = {"姓名",
          "語文",
          "數(shù)學(xué)",
          "總分",
          "及格",
          "作弊"};
          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();
          }
          }

          上例中表格內(nèi)的數(shù)據(jù)類型不論是 String,int 或是 Boolean 類型,都均以 string 的類型顯示.
          例如在及格的字段中,原本的數(shù)據(jù)是以 Boolean
          類型來表示,但顯示在 JTable 上時便轉(zhuǎn)換成字符串形式,若想要使表格能顯示出不同的數(shù)據(jù)類
          型,我們要在 MyTable 中 Override 寫 getColumnCl
          ass()方法,這個方法可以讓我們分辨出表格中每一行的數(shù)據(jù)類型,并將此類型作適當(dāng)?shù)娘@示:
          public Class getColumnClass(int c) {
          return getValueAt(0, c).getClass();
          }


          這樣"作弊"會以 Check Box 顯示,數(shù)據(jù)類型一律靠右顯示,String 類型一律靠左顯示.
          TableModel2.java
          import javax.swing.table.AbstractTableModel;
          import javax.swing.*;
          import java.awt.*;
          import java.awt.event.*;


          public class TableModel2 implements ActionListener
          {
          JTable t = null;
          public TableModel2() {
          JFrame f = new JFrame("DataModel");
          JButton b1 = new JButton("數(shù)學(xué)老師");
          b1.addActionListener(this);
          JButton b2 = new JButton("學(xué)生阿呆");
          b2.addActionListener(this);
          JPanel panel = new JPanel();
          panel.add(b1);
          panel.add(b2);
          t=new JTable(new MyTable(1));
          t.setPreferredScrollableViewportSize(new Dimension(550, 30));
          JScrollPane s = new JScrollPane(t);
          f.getContentPane().add(panel, BorderLayout.NORTH);
          f.getContentPane().add(s, BorderLayout.CENTER);
          f.pack();
          f.setVisible(true);
          f.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
          System.exit(0);
          }
          });
          }


          public void actionPerformed(ActionEvent e)
          {
             if (e.getActionCommand().equals("學(xué)生阿呆"))
             t.setModel(new MyTable(1));
             if (e.getActionCommand().equals("數(shù)學(xué)老師"))
             t.setModel(new MyTable(2));
             t.revalidate();
          }
          public static void main(String args[])
          {
             new TableModel2();
          }
          }
          class MyTable extends AbstractTableModel
          {
          Object[][] p1 = {
          {"阿呆", "1234",new Integer(66),
          new Integer(50), new Integer(116), new Boolean(false),new Boolean(false)}};
          String[] n1 = {"姓名","學(xué)號","語文","數(shù)學(xué)","總分","及格","作弊"};
          Object[][] p2 = {
          {"阿呆", "1234",new Integer(50), new Boolean(false),new Boolean(false),"01234"},
          {"阿瓜", "1235",new Integer(75), new Boolean(true),new Boolean(false),"05678"}};
          String[] n2 = {"姓名","學(xué)號","數(shù)學(xué)","及格","作弊","電話"};
          int model = 1;
          public MyTable(int i)
          {
              model = i;
          }
          public int getColumnCount()
          {
             if(model ==1)
             return n1.length;
             else
             return n2.length;
          }
          public int getRowCount()
          {
             if(model ==1)
             return p1.length;
             else
             return p2.length;
          }
          public String getColumnName(int col)
          {
             if(model ==1)
             return n1[col];
             else
             return n2[col];
          }
          public Object getValueAt(int row, int col)
          {
             if(model == 1)
             return p1[row][col];
             else
             return p2[row][col];
          }
          public Class getColumnClass(int c)
          {
             return getValueAt(0, c).getClass();
          }
          }

          TableColumnModel:

          TableColumnModel 本身是一個 Interface,里面定義了許多與表格的"列(行)"有關(guān)的方法,例
          如增加列,刪除列,設(shè)置與取得"列"的相關(guān)信
          息.通常我們不會直接實(shí)現(xiàn) TableColumnModel 界面,而是會利用 JTable 的 getColumnModel()
          方法取得 TableColumnModel 對象,再利用此對象對
          字段做設(shè)置.舉例來說,如果我們想設(shè)計(jì)的表格是包括有下拉式列表的 Combo Box,我們就能
          利用 TableColumnModel 來達(dá)到這樣的效果.
          我們先看看下面的例子:
          import javax.swing.table.AbstractTableModel;
          import javax.swing.*;
          import java.awt.*;
          import java.awt.event.*;
          public class ColumnModelTest
          {
          public ColumnModelTest()
          {
             JFrame f = new JFrame();

             /* 由 于 我 們 的 MyTable 類 繼 承 了 AbstractTableModel 并 且 實(shí) 作 了
             getColmunCount(),getRowCount(),getValueAt()方法.因此我們可以通
             *過 MyTable 來產(chǎn)生 TableModel 的實(shí)體.
             */
             MyTable mt=new MyTable();
             JTable t=new JTable(mt);//我們利用 MyTable 來建立 JTable.
             JComboBox c = new JComboBox();//建立一個 JComboBox 的對象.
             c.addItem("Taipei");//我們在新建立的 JComboBox 對象里新增三個項(xiàng)目.
             c.addItem("ChiaYi");
             c.addItem("HsinChu");
             /*我們利用 JTable 所提供的 getTableColumnModel()方法取得 TableColumnModel 對象,
             再由 TableColumnModel 類所提供的 getColumn()方
             *法取得 TableColumn 對象,TableColumn 類可針對表格中的每一行做具體的設(shè)置,例如
             設(shè)置字段的寬度,某行的標(biāo)頭,設(shè)置輸入較復(fù)雜的
             *數(shù)據(jù)類型等等.在這里,我們利用 TableColumn 類所提供的 setCellEditor()方法,將
             JComboBox 作為第二行的默認(rèn)編輯組件.
             */
             t.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(c));
             t.setPreferredScrollableViewportSize(new Dimension(550, 30));
             JScrollPane s = new JScrollPane(t);
             f.getContentPane().add(s, BorderLayout.CENTER);
             f.setTitle("ColumnModelTest");
             f.pack();
             f.setVisible(true);
             f.addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent e) {
             System.exit(0);
             }
             });
             }
             public static void main(String args[])
             {
              new ColumnModelTest();
             }


             }
             class MyTable extends AbstractTableModel{
             Object[][] p = {
             {"阿呆", "Taipei",new Integer(66),
             new Integer(32), new Integer(98), new Boolean(false),new Boolean(false)},
             {"阿瓜", "ChiaYi",new Integer(85),
             new Integer(69), new Integer(154), new Boolean(true),new Boolean(false)},
             };
             String[] n = {"姓名",
             "居住地",
             "語文",
             "數(shù)學(xué)",
             "總分",
             "及格",
             "作弊"};
             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();
          }
          }


          表格由兩部份組成:分別是行標(biāo)題(Column Header)與行對象(Column Object).利用 JTable
          所提供的 getTableHeader()方法取得行標(biāo)題。在這個例子中,我們將 JTable 放在 JScrollPane
          中,這種做法可以將 Column Header 與 Colmn Object 完整的顯示出來,因?yàn)?JScrollPane 會自
          動 取 得 Column Header. 但 如 果 文 壇 讀 者 將 上 面 第 15 行 去 掉 并 修 改 第 16 行 :
          f.getContentPane().add(table,BorderLayout.CENTER);
          則運(yùn)行結(jié)果你會發(fā)現(xiàn) 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);
          運(yùn)行結(jié)果就會跟之前一樣有行標(biāo)題了.
          上面的運(yùn)行結(jié)果就會跟發(fā)現(xiàn),每個字段的寬度都是一樣的,除非你自行拉曳某個列寬。若
          我們想一開始就設(shè)置列寬的值,可以利
          用 TableColumn 類所提供的 setPreferredWidth()方法來設(shè)置,并可利用 JTable 類所提供的
          setAutoResizeMode()方法來設(shè)置調(diào)整某個
          列寬時其他列寬的變化情況,我們看下面這個例字:
          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={"姓名","語文","數(shù)學(xué)","總分","及格","作弊"};
          TableColumn column=null;
          JTable table=new JTable(p,n);
          table.setPreferredScrollableViewportSize(new Dimension(550,30));
          table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
          for (int i=0;i<6;i++){
          //利用 JTable 中的 getColumnModel()方法取得 TableColumnModel 對象;再利用
          //TableColumnModel 界面所定義的 getColumn()方法取
          //TableColumn 對象,利用此對象的 setPreferredWidth()方法就可以控制字段的寬度.
          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("SimpleTable2");
          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();
          }
          }

          運(yùn)行結(jié)果:

          列可調(diào)整的 5 個參數(shù):
          AUTO_RESIZE_SUBSEQUENT_COLUMENS:當(dāng)調(diào)整某一列寬時,此字段之后的所有字段列
          寬都會跟著一起變動。此為系統(tǒng)默認(rèn)值。
          AUTO_RESIZE_ALL_COLUMNS:當(dāng)調(diào)整某一列寬時,此表格上所有字段的列寬都會跟著一
          起變動。
          AUTO_RESIZE_OFF:當(dāng)調(diào)整某一列寬時,此表格上所有字段列寬都不會跟著改變。
          AUTO_RESIZE_NEXT_COLUMN:當(dāng)調(diào)整某一列寬時,此字段的下一個字段的列寬會跟著改
          變,其余均不會變。
          AUTO_RESIZE_LAST_COLUMN:當(dāng)調(diào)整某一列寬時,最后一個字段的列寬會跟著改變,其
          余均不會改變。

          posted on 2008-09-12 15:31 liyang 閱讀(7371) 評論(0)  編輯  收藏

          主站蜘蛛池模板: 广州市| 柘城县| 黄大仙区| 唐山市| 清徐县| 章丘市| 芦溪县| 库尔勒市| 来宾市| 晋宁县| 合阳县| 南昌市| 金溪县| 武隆县| 仁怀市| 平顶山市| 禹城市| 东至县| 淮南市| 银川市| 麟游县| 怀集县| 永嘉县| 阳泉市| 周至县| 利辛县| 镇坪县| 苏尼特右旗| 长治市| 自治县| 莆田市| 天柱县| 台东县| 德清县| 洞口县| 华池县| 呼伦贝尔市| 琼中| 深州市| 吉林省| 灯塔市|