一個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中已經實現了大部分的經常使用方法,例如removeRow和insertRow,其中使用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