⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 beantablemodel.java

📁 本程序是有IBM开发的一个基于数据表格的组件,里面有相关的例子和DOC,本站资料仅为大家学习之用
💻 JAVA
字号:

package com.ibm.j2x.swing.table;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.swing.table.AbstractTableModel;

import org.apache.commons.collections.BeanMap;
import org.apache.commons.collections.map.LinkedMap;

import com.ibm.j2x.util.collection.ObservableCollection;
import com.ibm.j2x.event.CollectionEvent;
import com.ibm.j2x.event.CollectionListener;
import com.ibm.j2x.util.ClassUtilities;

/**
 * The BeanTableModel acts as the generic table model for all tables
 * in the TMF design.  Using the assumption that 99% of all tables are a list
 * of JavaBeans, the BeanTableModel utilizes introspection on these beans through
 * use of the Apache Jakarta Commons BeanMap to eliminate much of the code needed
 * in a classical Table Model.
 * <p>Introspection can be used to get and set the value, and can be used to get the
 * class of the column.
 * <p>The crucial information that's missing from the BeanTableModel that is needed
 * to make the table work properly is both the column name and the field in the JavaBean
 * that the introspection will use to display.  As an example of the field in a JavaBean,
 * a Bean with <code>getName()</code> and <code>setName()</code> functions would have a 
 * field name of <code>name</code>.  This column-field relationship is
 * treated as a key-value pairing.  Since the order is important, a traditional Map
 * cannot be used, and instead a Apache Jakarta Commons LinkedMap is used, which preserves
 * the order of the columns.  With the information from the LinkedMap, the BeanMap 
 * can return the correct field from the Bean.
 * <p>The noticable time that the BeanTableModel needs to be subclassed is when the table
 * needs to be editable.  The BeanTableModel should be subclasses with only the 
 * <code>isCellEditable()</code> function needing to be overridden.
 * 
 * @author MAbernethy
 */
public class BeanTableModel extends AbstractTableModel implements CollectionListener
{
	/** the list of BeanMaps */
	protected List mapValues = new ArrayList();
	/** the column information in key-value form */
	protected LinkedMap columnInfo = new LinkedMap();
	
	/**
	 * Creates a BeanTableModel with no column information.
	 */
	public BeanTableModel()
	{
		this(new ArrayList());
	}
	
	/**
	 * Creates a BeanTableModel with no column information and the specified
	 * data.
	 * @param values the data
	 */
	public BeanTableModel(Collection values)
	{
		this(values, new LinkedMap());
	}
	
	/**
	 * Creates a BeanTableModel with the specified data and column information.
	 * @param values the data
	 * @param columnInfo the column information
	 */
	public BeanTableModel(Collection values, LinkedMap columnInfo)
	{
		initializeValues(values);
		if (values instanceof ObservableCollection)
			((ObservableCollection)values).addCollectionListener(this);
		this.columnInfo = columnInfo;
	}	
	
	/**
	 * Initializes the values of the data.  During the initialization process,
	 * the BeanTableModel converts the data to a List, and then one by one, adds
	 * the contents of the list to a BeanMap which gets added to the list of BeanMaps.
	 * @param values the data
	 */
	protected void initializeValues(Collection values)
	{
		List listValues = new ArrayList(values);
		mapValues.clear();
		for (Iterator i=listValues.iterator(); i.hasNext();)
		{
			mapValues.add(new BeanMap(i.next()));
		}
	}
	
	/**
	 * Adds a column to the table.
	 * @param columnName the column name
	 * @param columnField the column field
	 */
	public void addColumn(Object columnName, Object columnField)
	{
		columnInfo.put(columnName, columnField);
		super.fireTableStructureChanged();
	}
	
	/**
	 * Sets the values in the table model.  This calls the protected
	 * <code>initializeValues()</code> function, and also checks to see
	 * if the data is an implementor of ObservableCollection, and if it is,
	 * registers this class as a listener for CollectionEvents.
	 * @param values the data
	 */
	public void setValues(Collection values) 
	{
		initializeValues(values);
		if (values instanceof ObservableCollection)
			((ObservableCollection)values).addCollectionListener(this);
		super.fireTableDataChanged();
	}
	
	/**
	 * Sets the column information.  The LinkedMap should be a key-value pairing of
	 * column name - column field in the order that the columns should be displayed.
	 * @param columnInfo 
	 */
	public void setColumnInfo(LinkedMap columnInfo)
	{
		this.columnInfo = columnInfo;
		super.fireTableStructureChanged();
	}

	/**
	 * Gets the row count.
	 * @return the number of rows of data
	 */
	public int getRowCount() 
	{
		return mapValues.size();
	}

	/**
	 * Gets the column count.
	 * @return the number of columns in the columninfo
	 */
	public int getColumnCount() 
	{
		return columnInfo.size();
	}

	/**
	 * Gets the column name.  It uses the column number to find the key-value pairing
	 * from the LinkedMap and returns the key, which is the column name.
	 * @param col the column number
	 * @return the column name
	 */
	public String getColumnName(int col) 
	{
		return columnInfo.get(col).toString();
	}
	
	/**
	 * Gets the column class.  The column class is found by retrieving the value
	 * from the BeanMap that should be returned and then getting the class from this value.
	 * Since the BeanMap automatically autoboxes the primitives (i.e. it converts int to
	 * Integer to store in the map, and then back to an int when retrieved), and this function
	 * may only return Objects, it converts primitives back to their corresponding
	 * Object types.
	 * @param col the column number
	 * @return the Class of the column (used for table rendering)
	 */
	public Class getColumnClass(int col) 
	{
		BeanMap map = (BeanMap)mapValues.get(0);
		Class c = map.getType(columnInfo.getValue(col).toString());
		if (c == null)
			return Object.class;
		else if (c.isPrimitive())
			return ClassUtilities.convertPrimitiveToObject(c);
		else
			return c;
	}

	/**
	 * Returns whether this cell is editable.  Always returns false.
	 * @param row the row number
	 * @param col the column number
	 * @return whether the cell is editable
	 */
	public boolean isCellEditable(int row, int col) 
	{
		return false;
	}

	/**
	 * Gets the value at the specified cell.  This returns the value by
	 * first getting the correct BeanMap from the list of BeanMaps using the 
	 * row number.  It then references the column information stored
	 * in the LinkedMap for the correct field, and uses this field to retrieve
	 * the value from the BeanMap.
	 * @param row the row number
	 * @param col the column number
	 * @return the value in the cell
	 */
	public Object getValueAt(int row, int col) 
	{
		BeanMap map = (BeanMap)mapValues.get(row);
		return map.get(columnInfo.getValue(col));
	}

	/**
	 * Sets the value at the specified cell.  This sets the value by
	 * first getting the correct BeanMap from the list of BeanMaps using the
	 * row number.  It then references the column information stored in the 
	 * LinkedMap for the correct field, and uses this field to retrieve the value
	 * from the BeanMap.
	 * @param value the new cell value
	 * @param row the row number
	 * @param col the column number
	 */
	public void setValueAt(Object value, int row, int col) 
	{
		BeanMap map = (BeanMap)mapValues.get(row);
		map.put(columnInfo.getValue(col), value);
		super.fireTableRowsUpdated(row, row);
	}

	/**
	 * Handles all changes to the data that occur and automatically
	 * updates the table.
	 * @param e the CollectionEvent
	 */
	public void collectionChanged(CollectionEvent e)
	{
		initializeValues((Collection)e.getSource());
		super.fireTableDataChanged();
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -