天天看點

Java圖形化:Swing表格的使用

利用JTable類直接建立表格

建立表格:

在JTable類中除了預設的構造方法之外,還提供了利用指定表格列名數組和表格資料數組建立表格的構造方法,如下:

JTable(Object[][] rowData,Object[] columnNames)

  • rowData就是表格的資料數組
  • columnNames就是表格的列名數組。

使用表格時,一般将其添加到滾動面闆中,然後将滾動面闆加到相應的位置。

在JTable中還提供了利用指定表格的列名向量和表格資料向量創造表格的構造方法,如下:

JTable(Vector rowData,Vector columnNames)

  • rowDara就是表格的資料向量
  • columnNames就是表格的列名向量

在使用表格時,有時候不需要使用滾動條,就可以在窗體中顯示整個表格,在這種情況下,也可以直接将表格添加到相應的容器中。

注意:如果是将表格添加到相應的容器中,則需要通過JTable類的

getTableHeader()

方法獲得JTableHeader類的對象,然後再将該對象添加到容器的相應位置,否則表格将沒有列名。

簡單表格案例:

package view.flight;

import javax.swing.*;
import java.awt.*;

/**
 * @author: 我的襪子都是洞
 */
public class TestGui extends JFrame {
    // 列名
    String[] columnName = new String[]{"航班号", "出發時間", "飛行時間", "出發地", "目的地", "餘票", "票價"};
    // 表格具體資料
    String[][] columnDate = new String[][]{
            {"1", "2019-01-18 10:05", "90分鐘", "北京", "紐約", "50", "500.0"},
            {"2", "2019-01-18 10:05", "90分鐘", "北京", "紐約", "10", "500.0"},
            {"3", "2019-01-18 10:05", "90分鐘", "北京", "紐約", "10", "500.0"},
            {"4", "2019-01-18 10:05", "90分鐘", "北京", "紐約", "40", "500.0"},
    };
    JTable table = new JTable(columnDate, columnName);

    TestGui(String title) {
        super(title);
        init();
        setComponent ();
        addComponent();
        addListener();
        setVisible(true);
    }
    private void init () {
        setSize(600, 400);
        // 設定視窗位置居中
        setLocationRelativeTo(null);
        // 設定布局
        setLayout(new BorderLayout());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    private void setComponent () {
        // 設定第一列寬度為40
        table.getColumnModel().getColumn(0).setPreferredWidth(40);
        // 設定第二列寬度為120
        table.getColumnModel().getColumn(1).setPreferredWidth(120);
        
    }
    private void addComponent () {
        // 使用srcllpane會自動顯示列名
        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane, BorderLayout.CENTER);
    }
    private void addListener () {

    }
    public static void main(String[] args) {
        new TestGui("JTable示範");
    }
}           

定制表格

表格建立之後,還需要對其進行一系列的定義,以便适合于具體的使用情況。預設情況下輕按兩下單元格便可對其編輯,如果不需要此功能,可以通過重構JTable類的

isCellEditable(int row,int column)

方法實作該方法傳回boolean型值true,表示可以編輯,否則傳回false則表示不可編輯。

可通過JTableHeader類的s

etReorderingAllowed(boolean reorderAllowed)

方法設定表格是否支援重新排列功能,該方法傳回boolean型值true表示支援,傳回false表示不支援。

預設情況下,單元格中的内容左側顯示,如果需要居中顯示,可通過重構JTable類的

getDefaultRenderer(Class<?> columnClass)

方法來實作。

重構的代碼:

public TableCellRenderer getDefaultRenderer(Class<?> columnClass) {
    DefaultTableCellRenderer cr=(DefaultTableCellRenderer)super.getDefaultRenderer(columnClass);
    cr.setHorizontalAlignment(DefaultTableCellRenderer.CENTER);
    return cr;
}           

JTable類的用來定義表格的常用方法

  • setRowHeight(int rowHeight)

    :設定表格的行高,預設像素為16
  • setRowSelectionAllowed(boolean sa)

    :設定是否允許選中表格行,預設為允許選中,設為false表示不允許選中
  • setSelectionMode(int sm)

    :設定表格行的選中模式
  • setSelectionBackground(Color  cr)

    :設定表格選中行的背景色
  • setSelectionForeground(Color  fc)

    :設定表格選中行的前景色
  • setAutoResizeMode(int mode)

    :設定表格的自動調整模式

在利用

setSelectionMode(int sm)

方法設定表格行的選擇模式時,它的入口參數從ListSelectionModel的靜态常量中選擇。如下:

  • 靜态常量:SINGLE_SELECTION,常量值:0,表示隻選擇一個。
  • 靜态常量:SINGLE_INTERVAL_SELECTION,常量值:1,表示允許連續選擇多個
  • 靜态常量:MULTIPLE_INTERVAL_SELECTION,常量值:2,表示随意選擇多個

setAutoResizeMode(int mode)

方法設定表格的自動調整模式時,它的入口參數從JTable類的靜态常量中選擇。

注意:表格的自動調整模式,就是在調整表格的某一列的寬度時,表格采用何種方式保持其總寬度不變。

操縱表格

在編寫應用程式時,經常需要獲得表格的一些資訊,如下是JTable類中的三個經常用來獲得表格資訊的方法。

  • getRowCount()

    :獲得表格擁有的行數,傳回值為int型。
  • getColumnCount()

    :獲得表格擁有的列數,傳回值為int型。
  • getColumnName(int column)

    :獲得位于指定索引位置的列的名稱,傳回值為String型。

JTable類中經常用來操縱表格選中行的方法如下:

  • setRowSelectionInterval(int from,int  to)

    :選中行索引從from到to的所有行(包括索引為from到to的行)
  • addRowSelectionInterval(int from,int to)

    :将行索引從from到to的所有行追加為表格的選中行
  • isRowSelected(int  row)

    :檢視行索引為row的行是否被選中
  • selectAll()

    :選中表格中的所有行
  • clearSelection()

    :取消所有選中行的選擇狀态
  • getSelectedRowCount()

    :得到選中行的數量,傳回值為int型,如果沒有被選中的行,則傳回-1
  • getSelectedRow()

    :得到被選中的行中最小的索引值,傳回值為int型,如果沒有被選中的行,則傳回-1

    -

    getSelectedRows()

    :獲得所有被選中行的索引值,傳回值為int數組

表格模型和表格

接口TableModel定義了一個表格模型,抽象類AbstracTableModel實作了TableModel接口的大部分方法,隻有以下3個抽象方法沒有實作。

  • public int getRowCount()

  • public int getColumnCount()

  • public Object getValueAt(int rowIndex,int columnIndex)

通過繼承AbstractTableModel可以實作上面的3個抽象方法可以建立自己的表格模型類。DefaultTableModel類便是由Swing類提供的繼承了AbstractTableModel類并實作了上面3個抽象方法的表格模型類。

從JDK1.6開始,提供了對表格進行排序的功能。通過JTable類的

setRowSorter(RowSorter<? extends TableModel> sorter)

方法可以為表格設定排序器。TableRowSorter類是由Swing提供的排序類,為表格設定排序器的代碼如下:

DefaultTableModel tableModel=new DefaultTableModel();
JTable table=new JTable(tableModel);
table.setRowSorter(new TableRowSorter(tableModel));           

在使用表格排序器時,通常需要為其設定表格模型,一種方法是通過構造方法

TableRowSorter(TableModel model)

,另一種方法是通過

setModel(TableModel  model)

方法為表格排序器設定表格模型。

維護表格模型

使用表格時,需要經常對表格中的内容進行維護,如向表格中添加新的資料行、修改表格中某一單元格的值、從表格中删除資料行等,這些操作都可以通過維護表格模型來完成。

在向表格模型中添加新的資料行時有兩種情況:一種是添加到表格模型的尾部,另一種是添加到表格模型指定的索引處,分别由

addRow(Object[] rowData)

insertRow(int row,Object[] rowData)

addRow(Vector rowData)

insertRow(int row,Vector rowData)

方法實作。

如果需要修改表格模型中某一個單元格的資料,可以通過方法

setValueAt(Object aValue,int row,int column)

完成,其中aValue就是修改後的值,可以通過

getValueAt(int row,int column)

獲得單元格的值,該方法傳回Object型。

如果需要删除表格模型中某一行的資料,可以通過方法

removeRow(int row)

來完成,其中row為欲要删除行的索引。

使用TableModel模型案例:

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.awt.*;

/**
 * @author: 我的襪子都是洞
 */
public class TestGui extends JFrame {

    JTable table = new JTable(new FlightTableModel());

    TestGui(String title) {
        super(title);
        init();
        setComponent ();
        addComponent();
        addListener();
        setVisible(true);
    }
    private void init () {
        setSize(600, 400);
        // 設定視窗位置居中
        setLocationRelativeTo(null);
        // 設定布局
        setLayout(new BorderLayout());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    private void setComponent () {
        // 設定第一列寬度為40
        table.getColumnModel().getColumn(0).setPreferredWidth(40);
        // 設定第二列寬度為120
        table.getColumnModel().getColumn(1).setPreferredWidth(120);

    }
    private void addComponent () {
        // 使用srcllpane會自動顯示列名
        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane, BorderLayout.CENTER);
    }
    private void addListener () {

    }
    public static void main(String[] args) {
        new TestGui("JTable示範");
    }
}

class FlightTableModel extends AbstractTableModel {
    // 列名
    String[] columnName = new String[]{"航班号", "出發時間", "飛行時間", "出發地", "目的地", "餘票", "票價"};
    // 表格具體資料
    String[][] flightDate = new String[][]{
            {"1", "2019-01-18 10:05", "90分鐘", "北京", "紐約", "50", "500.0"},
            {"2", "2019-01-18 10:05", "90分鐘", "北京", "紐約", "10", "500.0"},
            {"3", "2019-01-18 10:05", "90分鐘", "北京", "紐約", "10", "500.0"},
            {"4", "2019-01-18 10:05", "90分鐘", "北京", "紐約", "40", "500.0"},
    };
    /**
     * 傳回一共多少行
     */
    @Override
    public int getRowCount() {
        return flightDate.length;
    }

    /**
     * 傳回一共多少列
     */
    @Override
    public int getColumnCount() {
        return columnName.length;
    }

    /**
     * 傳回每一個單元格的值
     */
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        return flightDate[rowIndex][columnIndex];
    }

    /**
     * 擷取每一列的名稱
     */
    @Override
    public String getColumnName(int column) {
        return columnName[column];
    }

    /**
     * 單元格是否可以修改
     */
    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }
}           

效果:

通過監聽選中單元格擷取對應資料的執行個體:

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import java.awt.*;

/**
 * @author: 我的襪子都是洞
 */
public class TestGui extends JFrame {
    FlightTableModel flight = new FlightTableModel();
    JTable table = new JTable(flight);

    TestGui(String title) {
        super(title);
        init();
        setComponent ();
        addComponent();
        addListener();
        setVisible(true);
    }
    private void init () {
        setSize(600, 400);
        // 設定視窗位置居中
        setLocationRelativeTo(null);
        // 設定布局
        setLayout(new BorderLayout());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    private void setComponent () {
        // 設定第一列寬度為40
        table.getColumnModel().getColumn(0).setPreferredWidth(40);
        // 設定第二列寬度為120
        table.getColumnModel().getColumn(1).setPreferredWidth(120);

    }
    private void addComponent () {
        // 使用srcllpane會自動顯示列名
        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane, BorderLayout.CENTER);
    }
    private void addListener () {
        // selection監聽器監聽表格哪行被選中
        table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                // 被選中的行
                int row = table.getSelectedRow();
                String str = (String)flight.getValueAt(row,0);
                System.out.println("選中的行号是:"+row+",航班号是:"+str);
            }
        });
    }
    public static void main(String[] args) {
        new TestGui("JTable示範");
    }
}

class FlightTableModel extends AbstractTableModel {
    // 列名
    String[] columnName = new String[]{"航班号", "出發時間", "飛行時間", "出發地", "目的地", "餘票", "票價"};
    // 表格具體資料
    String[][] flightDate = new String[][]{
            {"1", "2019-01-18 10:05", "90分鐘", "北京", "紐約", "50", "500.0"},
            {"2", "2019-01-18 10:05", "90分鐘", "北京", "紐約", "10", "500.0"},
            {"3", "2019-01-18 10:05", "90分鐘", "北京", "紐約", "10", "500.0"},
            {"4", "2019-01-18 10:05", "90分鐘", "北京", "紐約", "40", "500.0"},
    };
    /**
     * 傳回一共多少行
     */
    @Override
    public int getRowCount() {
        return flightDate.length;
    }

    /**
     * 傳回一共多少列
     */
    @Override
    public int getColumnCount() {
        return columnName.length;
    }

    /**
     * 傳回每一個單元格的值
     */
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        return flightDate[rowIndex][columnIndex];
    }

    /**
     * 擷取每一列的名稱
     */
    @Override
    public String getColumnName(int column) {
        return columnName[column];
    }

    /**
     * 單元格是否可以修改
     */
    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }
}           

關鍵部分:

// selection監聽器監聽表格哪行被選中
        table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                // 被選中的行
                int row = table.getSelectedRow();
                String str = (String)flight.getValueAt(row,0);
                System.out.println("選中的行号是:"+row+",航班号是:"+str);
            }
        });           

擷取到的結果圖:

視窗圖:

資料: