Java Swing JTable 簡單總結

一個JTable對應一個有一個TableModel來管理它的數據,Jtable須要放入一個JscrollPane中來正常顯示,固然也能夠只顯示錶格內容、或者只顯示錶頭。 java

final GameListTable gameTable = new GameListTable();
GameListTableModel model = new GameListTableModel();
gameTable.setModel(model);
JScrollPane scrollPane = new JScrollPane(gameTable);
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 1;
mContainer.add(scrollPane, gbc);

TableModel中管理表格中數據,當編輯表格時,會觸發Model中的setValueAt方法,能夠在這裏觸發數據庫保存操做,當顯示錶格數據時,表格會逐行調用getValueAt方法將該方法返回值放入表格中。另外還有一些方法,如getRowCount肯定表格顯示多少行數據,getColumnName表格表頭的名字,isCellEditable若是須要一個單元格沒法編輯,則實現該方法,在指定的row和column時返回false。DefaultTableModel中已經實現了大部分的經常使用方法,例如removeRowinsertRow,其中使用dataVector這個變量保存表格每一行的值,具體能夠參看jdk源碼。git

import java.util.Date;
import java.util.List;
import java.util.Vector;

import javax.swing.table.DefaultTableModel;

import com.aquar.game.database.Company;
import com.aquar.game.database.EnumGameType;
import com.aquar.game.database.Game;
import com.aquar.game.dataserver.DataHandler;
import com.aquar.game.ulti.Ultility;

public class GameListTableModel extends DefaultTableModel {
    public static final int COL_NAME = 0;
    public static final int COL_TYPE = COL_NAME + 1;
    public static final int COL_DATE = COL_TYPE + 1;
    public static final int COL_COMPANY = COL_DATE + 1;
    public static final int COL_DATA = COL_COMPANY + 1;
    // not edit the cell by default
    private boolean editable = false;
    
    public GameListTableModel() {
        initColNames();
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void initData(List<Game> gameList) {
        dataVector.clear();
        if (gameList != null) {
            for (Game game : gameList) {
                Vector rowVector = new Vector();
                rowVector.add(COL_NAME, game.getName()); 
                rowVector.add(COL_TYPE, game.getType());
                rowVector.add(COL_DATE, game.getReleaseDate());
                rowVector.add(COL_COMPANY, game.getCompany());
                rowVector.add(COL_DATA, game);
                
                dataVector.add(rowVector);
            }
        }
        fireTableDataChanged();
    }

    @SuppressWarnings("unchecked")
    private void initColNames() {
        columnIdentifiers.add("Name");
        columnIdentifiers.add("Type");
        columnIdentifiers.add("Date");
        columnIdentifiers.add("Company");
        
    }
    
    @Override
    public int getRowCount() {
        return super.getRowCount();
    }
    
    @Override
    public Object getValueAt(int row, int column) {
        Object ret = "";
        Vector rowVector = (Vector) dataVector.elementAt(row);
        Object data =  rowVector.elementAt(column);
        if (data != null) {
            if (COL_TYPE == column) {
                int type = (int) data;
                ret = EnumGameType.getEnum(type);
            } else if (COL_DATE == column) {
                ret = Ultility.getDateStr((Date) data);
            } else {
                ret = data;
            }
        } else {
        }
        
        return ret;
    }
    
    @Override
    public void setValueAt(Object aValue, int row, int column) {
        Object oldValue = getValueAt(row, column);
        // not change anything.
        if (oldValue != null && oldValue.equals(aValue)) {
            return ;
        }
        
        // Get the Object of line.
        Vector rowVector = (Vector) dataVector.elementAt(row);
        Game game = (Game) rowVector.elementAt(COL_DATA);
        switch (column) {
        case COL_NAME:
            game.setName(aValue.toString().trim());
            break;
        case COL_TYPE:
            if (aValue instanceof EnumGameType) {
                EnumGameType type = (EnumGameType) aValue;
                game.setType(type.ordinal());
            }
            break;
        case COL_DATE:
            if (aValue instanceof Date) {
                game.setReleaseDate((Date) aValue);
            }
            break;
        case COL_COMPANY:
            if (aValue instanceof Company) {
                Company company = (Company) aValue;
                game.setCompany(company);
            }
            break;
        default:
            break;
        }
        DataHandler.getInstance().save(game);
    }
    
    @Override
    public boolean isCellEditable(int row, int column) {
        boolean ret = false;
        if (editable) {
            if (column == COL_DATE) {
            } else {
                ret = super.isCellEditable(row, column);
            }
        } else {
        }
        return ret;
        
    }
    
    public boolean isEditable() {
        return editable;
    }

    public void setEditable(boolean editable) {
        this.editable = editable;
    }
    
    public Object getSelectObject(int row) {
        Object ret = null;
        if (row < dataVector.size()) {
            Vector rowVector = (Vector) dataVector.elementAt(row);
            ret = rowVector.elementAt(COL_DATA);
        }
        return ret;
    }
}

當表格處於編輯狀態時,會調用CellEditor來提供編輯入口,經過自定義CellEditor能夠設置不一樣的單元格編輯框的樣式,能夠是JcomboBox、JtextField、JcheckBox等文本輸入控件。能夠按照對象類型設置全部某個對象類型的單元格都是一種CellEditor也是按照列來分別設置不一樣的列使用不一樣的編輯器。 github

 

private void initTable(final GameListTable gameTable) {
        EnumGameType[] types = EnumGameType.values();
        JComboBox<EnumGameType> typeBox = new JComboBox<EnumGameType>(types);
        gameTable.getColumnModel().getColumn(GameListTableModel.COL_TYPE).setCellEditor(new CustomCellEditor(typeBox));
        
        JComboBox<Company> companyBox = new JComboBox<>();
        List<Company> companies = DataCache.getInstance().getComanies();
        if (companies != null) {
            companyBox.setModel(
                    new DefaultComboBoxModel<Company>(
                            (Company[]) companies.toArray(new Company[companies.size()])));
        }
        gameTable.getColumnModel().getColumn(GameListTableModel.COL_COMPANY).setCellEditor(new CustomCellEditor(companyBox));
        gameTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        
        gameTable.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    int col = gameTable.columnAtPoint(e.getPoint());
                    int row = gameTable.rowAtPoint(e.getPoint());
                    if (GameListTableModel.COL_DATE == col) {
                        Window parentWindow = SwingUtilities
                                .windowForComponent(mContainer);
                        DatePickerDialog dialog = new DatePickerDialog(parentWindow);
                        dialog.setVisible(true);
                        if (dialog.isChanged()) {
                            gameTable.setValueAt(dialog.getDateValue().getTime(), row, col);
                        }
                    }
                }
                super.mousePressed(e);
            }
        });
    }

TableCellEditor是一個接口,只有一個方法getTableCellEditorComponent該方法返回的Component將會顯示在表格的某一個格子中,供用戶編輯輸入。通常只須要繼承DefaultCellEditor,對已經實現的功能根據特殊須要就行覆蓋便可。在實現Combobox時,默認狀況下,Combobox不會選擇表格的當前值做爲選項列表的默認值,須要在方法getTableCellEditorComponent中,將表格的當前值選擇上。 數據庫

import java.awt.Component;

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JTable;

/**
 * @author Edison
 * Custom a TableCellEditor for get right select when edit.
 */
public class CustomCellEditor extends DefaultCellEditor {

    public CustomCellEditor(JComboBox comboBox) {
        super(comboBox);
        // TODO Auto-generated constructor stub
    }
    
    @Override
    public Component getTableCellEditorComponent(JTable table, Object value,
            boolean isSelected, int row, int column) {
        // TODO Auto-generated method stub
        Component com = super.getTableCellEditorComponent(table, value, isSelected, row, column);
        if (com instanceof JComboBox<?>) {
            ((JComboBox<?>) com).setSelectedItem(value);
            Object obj = ((JComboBox) com).getSelectedItem();
            System.out.println(obj);
        }
        return com;
    }
}

當表格沒有在編輯狀態時,表格使用CellRender來顯示錶格的每個單元格,一樣能夠根據數據類型或者列來設置每一列甚至某個單元格的樣式。 編輯器

import javax.swing.JTable;

public class GameListTable extends JTable {
    public GameListTable() {
        // exit edit status when lose focus.
        putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
        setDefaultRenderer(Object.class, new CustomCellRender());
        setRowHeight(26);
    }       
}

CellRender通常都是JLabel對象,只須要繼承DefaultTableCellRenderer類覆蓋其中的getTableCellRendererComponent方法,該方法返回的控件在顯示錶格時會被調用,所以在其中能夠對顯示文字樣式、背景色進行調整,返回控件便可。 ide

import java.awt.Color;
import java.awt.Component;

import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

public class CustomCellRender extends DefaultTableCellRenderer {
    private Color oddLineColor = new Color(45, 210, 150);
    private Color evenLineColor = new Color(210, 150, 40);
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
        // TODO Auto-generated method stub
        Component com =  super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
                row, column);
        if (row % 2 == 0) {
            com.setBackground(oddLineColor);
        } else {
            com.setBackground(evenLineColor);
        }
        return com;
    }
}

 

一個簡單Swing數據庫程序例子 GameStore  this

相關文章
相關標籤/搜索