Java圖形化:Swing表格的使用

我的襪子都是洞發表於2019-02-16

利用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介面

定製表格

表格建立之後,還需要對其進行一系列的定義,以便適合於具體的使用情況。預設情況下雙擊單元格便可對其編輯,如果不需要此功能,可以通過重構JTable類的isCellEditable(int row,int column)方法實現該方法返回boolean型值true,表示可以編輯,否則返回false則表示不可編輯。

可通過JTableHeader類的setReorderingAllowed(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;
    }
}
複製程式碼

效果:

使用TableModel的案例

通過監聽選中單元格獲取對應資料的例項:

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);
            }
        });
複製程式碼

獲取到的結果圖: 視窗圖:

視窗

資料:

資料

相關文章