Swing JtableModel 使用之旅
JTable 是我们一般展示数据的一个很好的Grid组建,个人认为在使用swing 组建时对其model的定义很重要,今天鄙人做了小小研究,定义了自己的TableModel,甚是高兴,于是分享出来与大家共同进步。
首先定义我们要展示的数据模型:
MyData.java
package table;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import table.MyTableDataModel.MyTableColumn;
/**
* My dataModel
* @author Lyon Yao
*
*/
public class MyData {
private String name;
private String sex;
private String cellphone;
private String address;
private Boolean isSelected;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getCellphone() {
return cellphone;
}
public void setCellphone(String cellphone) {
this.cellphone = cellphone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Object isSelected() {
return this.isSelected;
}
public void setSelected(Boolean value){
this.isSelected=value;
}
public HashMap<MyTableColumn, String> validate() {
HashMap<MyTableColumn, String> result=new HashMap<MyTableDataModel.MyTableColumn, String>(0);
if(this.name==null||this.name.isEmpty()){
result.put(MyTableColumn.NAME, "Please Input Name");
}
if(!isNumeric(this.cellphone)){
result.put(MyTableColumn.CELLPHONE, "Please Input Correct CellPhone");
}
return result;
}
public boolean isNumeric(String str) {
Pattern pattern = Pattern.compile("[0-9]*");
Matcher isNum = pattern.matcher(str);
if (!isNum.matches()) {
return false;
}
return true;
}
}
然后去定义我的TableModel,比较扯,我将renderer和editor也在model里面做了关联定义,只在使用时候调用的。
MyTableDataModel.java
package table;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
/**
* this class is used to difine the table's model,in this class,we defined
* column's cell editor and renderer
* @author Lyon Yao
*
*/
public class MyTableDataModel extends AbstractTableModel {
/**
*
*/
private static final long serialVersionUID = -7312994273683436365L;
enum MyTableColumn implements ValueOperate{
IS_SELECTED(""){
@Override
public Object getValue(MyData rowData) {
return rowData.isSelected();
}
@Override
public void setValue(MyData rowData, Object obj) {
rowData.setSelected(obj==null?false:Boolean.valueOf(obj.toString()));
}
@Override
public TableCellEditor getCellEditor() {
return new DefaultCellEditor(new JCheckBox());
}
@Override
public TableCellRenderer getCellRenderer() {
return new TableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
JCheckBox checkBox=new JCheckBox();
checkBox.setSelected((Boolean)value);
return checkBox;
}
};
}
@Override
public int getMinWidth() {
return 25;
}
@Override
public int getMaxWidth() {
return 25;
}
},NAME("Name"){
@Override
public Object getValue(MyData rowData) {
return rowData.getName();
}
@Override
public void setValue(MyData rowData,Object obj) {
if(obj==null)return;
rowData.setName(obj.toString());
}
@Override
public int getMinWidth() {
return 100;
}
@Override
public int getMaxWidth() {
return 200;
}
},SEX("Sex"){
@Override
public Object getValue(MyData rowData) {
return rowData.getSex();
}
@Override
public void setValue(MyData rowData,Object obj) {
rowData.setSex(obj==null?null:obj.toString());
}
@Override
public TableCellEditor getCellEditor() {
JComboBox box=new JComboBox();
box.addItem("Male");
box.addItem("Famale");
return new DefaultCellEditor(box);
}
@Override
public TableCellRenderer getCellRenderer() {
return new TableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
JComboBox box=new JComboBox();
box.addItem(value);
box.setSelectedIndex(0);
return box;
}
};
}
@Override
public int getMinWidth() {
return 70;
}
@Override
public int getMaxWidth() {
return 120;
}
},CELLPHONE("Cellphone"){
@Override
public Object getValue(MyData rowData) {
return rowData.getCellphone();
}
@Override
public void setValue(MyData rowData,Object obj) {
rowData.setCellphone(obj==null?null:obj.toString());
}
@Override
public int getMinWidth() {
return 150;
}
@Override
public int getMaxWidth() {
return 150;
}
},ADRESS("Address"){
@Override
public Object getValue(MyData rowData) {
return rowData.getAddress();
}
@Override
public void setValue(MyData rowData,Object obj) {
rowData.setAddress(obj==null?null:obj.toString());
}
@Override
public int getMinWidth() {
return 200;
}
@Override
public int getMaxWidth() {
return 1000;
}
};
private final String name;
private TableCellEditor editor;
private TableCellRenderer renderer;
private MyTableColumn(String name) {
this.name = name;
}
@Override
public void setCellEditor(TableCellEditor editor) {
this.editor=editor;
}
@Override
public void setCellRenderer(TableCellRenderer renderer) {
this.renderer=renderer;
}
@Override
public String toString() {
return this.name;
}
@Override
public TableCellEditor getCellEditor() {
return this.editor;
}
@Override
public TableCellRenderer getCellRenderer() {
return this.renderer;
}
}
interface ValueOperate{
Object getValue(MyData rowData);
void setValue(MyData rowData,Object obj);
TableCellEditor getCellEditor();
TableCellRenderer getCellRenderer();
void setCellEditor(TableCellEditor editor);
void setCellRenderer(TableCellRenderer renderer);
int getMinWidth();
int getMaxWidth();
}
private final List<MyData> data;
private static BufferedImage dash;
static{
try {
dash=ImageIO.read(MyTableDataModel.class.getClassLoader().getResources("table\\dash.png").nextElement());
} catch (IOException e) {
e.printStackTrace();
}
; }
public MyTableDataModel(List<MyData> data) {
super();
this.data = data;
setUpColumEidtors();
setUpColumnRenders();
}
private void setUpColumEidtors(){
final DefaultCellEditor editor=new DefaultCellEditor(new JTextField());
for(MyTableColumn col:MyTableColumn.values()){
col.setCellEditor(editor);
}
}
public void addItem(MyData data){
this.data.add(data);
fireTableDataChanged();
}
public void delete(MyData data){
if(data!=null){
this.data.remove(data);
fireTableDataChanged();
}
}
public void delete(int index){
if(index>-1&&index<this.data.size()){
this.data.remove(index);
fireTableDataChanged();
}
}
private void setUpColumnRenders(){
final DefaultTableCellRenderer renderer=new DefaultTableCellRenderer(){
/**
*
*/
private static final long serialVersionUID = 2330186726723746657L;
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
Component component= super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
row, column);
HashMap<MyTableColumn, String> errorData = isErrorData(row,column);
if(!errorData.isEmpty()){
final JPanel panel=new JPanel(new BorderLayout()){
/**
*
*/
private static final long serialVersionUID = -6170683167857459445L;
@Override
public void paint(Graphics g) {
super.paint(g);
final int cc=(int) Math.round((getWidth()*1.0/dash.getWidth()));
for(int i=0;i<cc;i++){
g.drawImage(dash, i*dash.getWidth(), getHeight()-dash.getHeight(),null);
}
}
};
panel.add(component);
panel.setToolTipText(errorData.get(getColumnByIndex(column)));
component=panel;
}
return component;
}
};
for(MyTableColumn col:MyTableColumn.values()){
col.setCellRenderer(renderer);
}
}
private MyTableColumn getColumnByIndex(int column){
return MyTableColumn.values()[column];
}
private HashMap<MyTableColumn,String> isErrorData(int row,int column){
MyData rowData=data.get(row);
HashMap<MyTableColumn, String> result=new HashMap<MyTableDataModel.MyTableColumn, String>(0);
HashMap<MyTableColumn, String> validte= rowData.validate();
for(MyTableColumn col:validte.keySet()){
if(col.ordinal()==column){
result.put(col, validte.get(col));
}
}
return result;
}
@Override
public int getRowCount() {
return this.data.size();
}
@Override
public int getColumnCount() {
return MyTableColumn.values().length;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
MyData row=data.get(rowIndex);
for(MyTableColumn column:MyTableColumn.values()){
if(column.ordinal()==columnIndex)
return column.getValue(row);
}
return null;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
MyData row=data.get(rowIndex);
for(MyTableColumn column:MyTableColumn.values()){
if(column.ordinal()==columnIndex)
column.setValue(row,aValue);
}
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
}
好了 核心的东西已经出来了,下面写个测试类玩玩:)
TableExample.java
package table;
import java.awt.HeadlessException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.WindowConstants;
public class TableExample extends JFrame {
/**
*
*/
private static final long serialVersionUID = -5180906807674700787L;
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new TableExample();
}
private TableExample() throws HeadlessException {
super();
this.setBounds(200, 200, 1024, 768);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.creatTable();
this.setVisible(true);
}
private void creatTable() {
final List<MyData> data=new ArrayList<MyData>(0);
MyData myData = new MyData();
myData.setName("xxxddd");
myData.setAddress("XXOOXXOO");
myData.setCellphone("11392901");
myData.setSex("Famale");
myData.setSelected(true);
data.add(myData);
myData = new MyData();
myData.setName("xxxddd");
myData.setAddress("XXOOXXOO");
myData.setCellphone("11392901");
myData.setSex("Famale");
myData.setSelected(true);
data.add(myData);
myData = new MyData();
myData.setName("xxxddd");
myData.setAddress("XXOOXXOO");
myData.setCellphone("11392901");
myData.setSex("Famale");
myData.setSelected(true);
data.add(myData);
JTable table=new JTable(new MyTableDataModel(data));
table.setRowHeight(20);
for( MyTableDataModel.MyTableColumn column:MyTableDataModel.MyTableColumn.values())
{
table.getColumnModel().getColumn(column.ordinal()).setHeaderValue(column);
table.getColumnModel().getColumn(column.ordinal()).setCellEditor(column.getCellEditor());
table.getColumnModel().getColumn(column.ordinal()).setCellRenderer(column.getCellRenderer());
table.getColumnModel().getColumn(column.ordinal()).setMaxWidth(column.getMaxWidth());
table.getColumnModel().getColumn(column.ordinal()).setMinWidth(column.getMinWidth());
}
JScrollPane panle=new JScrollPane(table);
this.add(panle);
}
}
大功告成,试运行如图: