Java圖形化:Swing表格的使用

利用JTable類直接創(chuàng)建表格

創(chuàng)建表格:

在JTable類中除了默認(rèn)的構(gòu)造方法之外份蝴,還提供了利用指定表格列名數(shù)組和表格數(shù)據(jù)數(shù)組創(chuàng)建表格的構(gòu)造方法氓轰,如下:

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

  • rowData就是表格的數(shù)據(jù)數(shù)組
  • columnNames就是表格的列名數(shù)組署鸡。

使用表格時(shí),一般將其添加到滾動(dòng)面板中靴庆,然后將滾動(dòng)面板加到相應(yīng)的位置炉抒。

在JTable中還提供了利用指定表格的列名向量和表格數(shù)據(jù)向量創(chuàng)造表格的構(gòu)造方法,如下:
JTable(Vector rowData禽笑,Vector columnNames)

  • rowDara就是表格的數(shù)據(jù)向量
  • columnNames就是表格的列名向量

在使用表格時(shí),有時(shí)候不需要使用滾動(dòng)條僚稿,就可以在窗體中顯示整個(gè)表格蟀伸,在這種情況下,也可以直接將表格添加到相應(yīng)的容器中蠢络。

注意:如果是將表格添加到相應(yīng)的容器中迟蜜,則需要通過JTable類的getTableHeader()方法獲得JTableHeader類的對象,然后再將該對象添加到容器的相應(yīng)位置髓霞,否則表格將沒有列名畦戒。

簡單表格案例:

package view.flight;

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

/**
 * @author: 我的襪子都是洞
 */
public class TestGui extends JFrame {
    // 列名
    String[] columnName = new String[]{"航班號(hào)", "出發(fā)時(shí)間", "飛行時(shí)間", "出發(fā)地", "目的地", "余票", "票價(jià)"};
    // 表格具體數(shù)據(jù)
    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);
        // 設(shè)置窗口位置居中
        setLocationRelativeTo(null);
        // 設(shè)置布局
        setLayout(new BorderLayout());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    private void setComponent () {
        // 設(shè)置第一列寬度為40
        table.getColumnModel().getColumn(0).setPreferredWidth(40);
        // 設(shè)置第二列寬度為120
        table.getColumnModel().getColumn(1).setPreferredWidth(120);
        
    }
    private void addComponent () {
        // 使用srcllpane會(huì)自動(dòng)顯示列名
        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane, BorderLayout.CENTER);
    }
    private void addListener () {

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

定制表格

表格創(chuàng)建之后纵潦,還需要對其進(jìn)行一系列的定義垃环,以便適合于具體的使用情況。默認(rèn)情況下雙擊單元格便可對其編輯被济,如果不需要此功能涧团,可以通過重構(gòu)JTable類的isCellEditable(int row泌绣,int column)方法實(shí)現(xiàn)該方法返回boolean型值true,表示可以編輯阿迈,否則返回false則表示不可編輯。

可通過JTableHeader類的setReorderingAllowed(boolean reorderAllowed)方法設(shè)置表格是否支持重新排列功能刊棕,該方法返回boolean型值true表示支持甥角,返回false表示不支持。

默認(rèn)情況下震束,單元格中的內(nèi)容左側(cè)顯示当犯,如果需要居中顯示,可通過重構(gòu)JTable類的getDefaultRenderer(Class<嘉栓?> columnClass)方法來實(shí)現(xiàn)驰凛。
重構(gòu)的代碼:

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

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

  • setRowHeight(int rowHeight):設(shè)置表格的行高恰响,默認(rèn)像素為16
  • setRowSelectionAllowed(boolean sa):設(shè)置是否允許選中表格行涌献,默認(rèn)為允許選中,設(shè)為false表示不允許選中
  • setSelectionMode(int sm):設(shè)置表格行的選中模式
  • setSelectionBackground(Color cr):設(shè)置表格選中行的背景色
  • setSelectionForeground(Color fc):設(shè)置表格選中行的前景色
  • setAutoResizeMode(int mode):設(shè)置表格的自動(dòng)調(diào)整模式

在利用setSelectionMode(int sm)方法設(shè)置表格行的選擇模式時(shí)枢劝,它的入口參數(shù)從ListSelectionModel的靜態(tài)常量中選擇卜壕。如下:

  • 靜態(tài)常量:SINGLE_SELECTION,常量值:0,表示只選擇一個(gè)鹤盒。
  • 靜態(tài)常量:SINGLE_INTERVAL_SELECTION,常量值:1侦副,表示允許連續(xù)選擇多個(gè)
  • 靜態(tài)常量:MULTIPLE_INTERVAL_SELECTION,常量值:2秦驯,表示隨意選擇多個(gè)

在利用setAutoResizeMode(int mode)方法設(shè)置表格的自動(dòng)調(diào)整模式時(shí),它的入口參數(shù)從JTable類的靜態(tài)常量中選擇亲桥。

注意:表格的自動(dòng)調(diào)整模式,就是在調(diào)整表格的某一列的寬度時(shí)皂甘,表格采用何種方式保持其總寬度不變悼凑。

操縱表格

在編寫應(yīng)用程序時(shí),經(jīng)常需要獲得表格的一些信息渐夸,如下是JTable類中的三個(gè)經(jīng)常用來獲得表格信息的方法渔欢。

  • getRowCount():獲得表格擁有的行數(shù),返回值為int型苫幢。
  • getColumnCount():獲得表格擁有的列數(shù)垫挨,返回值為int型九榔。
  • getColumnName(int column):獲得位于指定索引位置的列的名稱,返回值為String型哲泊。

JTable類中經(jīng)常用來操縱表格選中行的方法如下:

  • setRowSelectionInterval(int from切威,int to):選中行索引從from到to的所有行(包括索引為from到to的行)
  • addRowSelectionInterval(int from,int to):將行索引從from到to的所有行追加為表格的選中行
  • isRowSelected(int row):查看行索引為row的行是否被選中
  • selectAll():選中表格中的所有行
  • clearSelection():取消所有選中行的選擇狀態(tài)
  • getSelectedRowCount():得到選中行的數(shù)量且预,返回值為int型烙无,如果沒有被選中的行截酷,則返回-1
  • getSelectedRow():得到被選中的行中最小的索引值,返回值為int型,如果沒有被選中的行鼓择,則返回-1
    -getSelectedRows():獲得所有被選中行的索引值就漾,返回值為int數(shù)組

表格模型和表格

接口TableModel定義了一個(gè)表格模型抑堡,抽象類AbstracTableModel實(shí)現(xiàn)了TableModel接口的大部分方法,只有以下3個(gè)抽象方法沒有實(shí)現(xiàn)偎漫。

  • public int getRowCount()
  • public int getColumnCount()
  • public Object getValueAt(int rowIndex有缆,int columnIndex)

通過繼承AbstractTableModel可以實(shí)現(xiàn)上面的3個(gè)抽象方法可以創(chuàng)建自己的表格模型類。DefaultTableModel類便是由Swing類提供的繼承了AbstractTableModel類并實(shí)現(xiàn)了上面3個(gè)抽象方法的表格模型類杯矩。

從JDK1.6開始袖外,提供了對表格進(jìn)行排序的功能在刺。通過JTable類的setRowSorter(RowSorter<? extends TableModel> sorter)方法可以為表格設(shè)置排序器头镊。TableRowSorter類是由Swing提供的排序類,為表格設(shè)置排序器的代碼如下:

DefaultTableModel tableModel=new DefaultTableModel()颖杏;
JTable table=new JTable(tableModel)坛芽;
table.setRowSorter(new TableRowSorter(tableModel));

在使用表格排序器時(shí)咙轩,通常需要為其設(shè)置表格模型,一種方法是通過構(gòu)造方法TableRowSorter(TableModel model)活喊,另一種方法是通過setModel(TableModel model)方法為表格排序器設(shè)置表格模型。

維護(hù)表格模型

使用表格時(shí)帅矗,需要經(jīng)常對表格中的內(nèi)容進(jìn)行維護(hù)浑此,如向表格中添加新的數(shù)據(jù)行、修改表格中某一單元格的值紊馏、從表格中刪除數(shù)據(jù)行等最冰,這些操作都可以通過維護(hù)表格模型來完成。

在向表格模型中添加新的數(shù)據(jù)行時(shí)有兩種情況:一種是添加到表格模型的尾部赌朋,另一種是添加到表格模型指定的索引處篇裁,分別由addRow(Object[] rowData)insertRow(int row达布,Object[] rowData)addRow(Vector rowData)insertRow(int row,Vector rowData)方法實(shí)現(xiàn)躺苦。

如果需要修改表格模型中某一個(gè)單元格的數(shù)據(jù)产还,可以通過方法setValueAt(Object aValue,int row愈诚,int column)完成牛隅,其中aValue就是修改后的值媒佣,可以通過getValueAt(int row,int column)獲得單元格的值欢嘿,該方法返回Object型。

如果需要?jiǎng)h除表格模型中某一行的數(shù)據(jù)碘耳,可以通過方法removeRow(int row)來完成框弛,其中row為欲要?jiǎng)h除行的索引。

使用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);
        // 設(shè)置窗口位置居中
        setLocationRelativeTo(null);
        // 設(shè)置布局
        setLayout(new BorderLayout());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    private void setComponent () {
        // 設(shè)置第一列寬度為40
        table.getColumnModel().getColumn(0).setPreferredWidth(40);
        // 設(shè)置第二列寬度為120
        table.getColumnModel().getColumn(1).setPreferredWidth(120);

    }
    private void addComponent () {
        // 使用srcllpane會(huì)自動(dòng)顯示列名
        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[]{"航班號(hào)", "出發(fā)時(shí)間", "飛行時(shí)間", "出發(fā)地", "目的地", "余票", "票價(jià)"};
    // 表格具體數(shù)據(jù)
    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;
    }

    /**
     * 返回每一個(gè)單元格的值
     */
    @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的案例

通過監(jiān)聽選中單元格獲取對應(yīng)數(shù)據(jù)的實(shí)例:

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);
        // 設(shè)置窗口位置居中
        setLocationRelativeTo(null);
        // 設(shè)置布局
        setLayout(new BorderLayout());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    private void setComponent () {
        // 設(shè)置第一列寬度為40
        table.getColumnModel().getColumn(0).setPreferredWidth(40);
        // 設(shè)置第二列寬度為120
        table.getColumnModel().getColumn(1).setPreferredWidth(120);

    }
    private void addComponent () {
        // 使用srcllpane會(huì)自動(dòng)顯示列名
        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane, BorderLayout.CENTER);
    }
    private void addListener () {
        // selection監(jiān)聽器監(jiān)聽表格哪行被選中
        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("選中的行號(hào)是:"+row+",航班號(hào)是:"+str);
            }
        });
    }
    public static void main(String[] args) {
        new TestGui("JTable演示");
    }
}

class FlightTableModel extends AbstractTableModel {
    // 列名
    String[] columnName = new String[]{"航班號(hào)", "出發(fā)時(shí)間", "飛行時(shí)間", "出發(fā)地", "目的地", "余票", "票價(jià)"};
    // 表格具體數(shù)據(jù)
    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;
    }

    /**
     * 返回每一個(gè)單元格的值
     */
    @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;
    }
}

關(guān)鍵部分:

// selection監(jiān)聽器監(jiān)聽表格哪行被選中
        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("選中的行號(hào)是:"+row+",航班號(hào)是:"+str);
            }
        });

獲取到的結(jié)果圖:
窗口圖:


窗口

數(shù)據(jù):


數(shù)據(jù)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末虑啤,一起剝皮案震驚了整個(gè)濱河市架馋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌萍启,老刑警劉巖屏鳍,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钓瞭,死亡現(xiàn)場離奇詭異,居然都是意外死亡降淮,警方通過查閱死者的電腦和手機(jī)佳鳖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門媒惕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人穿挨,你說我怎么就攤上這事∶毖茫” “怎么了贞绵?”我有些...
    開封第一講書人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵榨崩,是天一觀的道長。 經(jīng)常有香客問我翩剪,道長彩郊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任博杖,我火速辦了婚禮筷登,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘狈醉。我一直安慰自己惠险,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開白布渣慕。 她就那樣靜靜地躺著抱慌,像睡著了一般抑进。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上寺渗,一...
    開封第一講書人閱讀 52,713評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音汁果,去河邊找鬼玲躯。 笑死,一個(gè)胖子當(dāng)著我的面吹牛晋控,可吹牛的內(nèi)容都是我干的姓赤。 我是一名探鬼主播,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼蝌焚,長吁一口氣:“原來是場噩夢啊……” “哼誓斥!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起毕谴,我...
    開封第一講書人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬榮一對情侶失蹤涝开,失蹤者是張志新(化名)和其女友劉穎框仔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體银舱,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡跛梗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年茄袖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嘁锯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片聂薪。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡藏澳,死狀恐怖耀找,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蓄愁,我是刑警寧澤狞悲,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布摇锋,位于F島的核電站,受9級(jí)特大地震影響荸恕,放射性物質(zhì)發(fā)生泄漏融求。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一施掏、第九天 我趴在偏房一處隱蔽的房頂上張望茅糜。 院中可真熱鬧,春花似錦蔑赘、人聲如沸缩赛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旨袒。三九已至术辐,卻和暖如春施无,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瑞躺。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來泰國打工幢哨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嫂便,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓曼振,卻偏偏與公主長得像蔚龙,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子木羹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361