1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
|
/* Glazed Lists (c) 2003-2006 */
/* http://publicobject.com/glazedlists/ publicobject.com,*/
/* O'Dell Engineering Ltd.*/
package ca.odell.glazedlists.impl.beans;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.gui.AdvancedTableFormat;
import ca.odell.glazedlists.gui.WritableTableFormat;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Collections;
/**
* TableFormat implementation that uses reflection to be used for any
* JavaBean-like Object with getProperty() and setProperty() style API.
*
* @author <a href="mailto:jesse@swank.ca">Jesse Wilson</a>
* @author <a href="mailto:andrea.aime@aliceposta.it">Andrea Aime</a>
*/
public class BeanTableFormat<E> implements WritableTableFormat<E>, AdvancedTableFormat<E> {
/** methods for extracting field values */
protected BeanProperty<E>[] beanProperties = null;
/** Java Beans property names */
protected String[] propertyNames;
/** column labels are pretty-print column header labels */
protected String[] columnLabels;
/** whether all columns can be edited */
private boolean[] editable;
/** column comparators */
protected Comparator[] comparators;
/** column classes */
protected Class[] classes;
/** primitive class to object class conversion map */
protected static final Map<Class,Class> primitiveToObjectMap;
static {
Map<Class,Class> primitiveToObjectMapWritable = new HashMap<Class,Class>();
primitiveToObjectMapWritable.put(boolean.class, Boolean.class);
primitiveToObjectMapWritable.put(char.class, Character.class);
primitiveToObjectMapWritable.put(byte.class, Byte.class);
primitiveToObjectMapWritable.put(short.class, Short.class);
primitiveToObjectMapWritable.put(int.class, Integer.class);
primitiveToObjectMapWritable.put(long.class, Long.class);
primitiveToObjectMapWritable.put(float.class, Float.class);
primitiveToObjectMapWritable.put(double.class, Double.class);
primitiveToObjectMap = Collections.unmodifiableMap(primitiveToObjectMapWritable);
}
/**
* Create a BeanTableFormat that uses the specified column names
* and the specified field names while offering editable columns.
*/
public BeanTableFormat(Class<E> beanClass, String[] propertyNames, String[] columnLabels, boolean[] editable) {
this.propertyNames = propertyNames;
this.columnLabels = columnLabels;
this.editable = editable;
// set up the AdvancedTableFormat properties
comparators = new Comparator[propertyNames.length];
classes = new Class[propertyNames.length];
// use default properties if no class is specified
if(beanClass == null) {
for(int c = 0; c < classes.length; c++) {
classes[c] = Object.class;
comparators[c] = GlazedLists.comparableComparator();
}
// use detected properties if class is specified
} else {
loadPropertyDescriptors(beanClass);
for(int c = 0; c < classes.length; c++) {
// class
Class rawClass = beanProperties[c].getValueClass();
if(primitiveToObjectMap.containsKey(rawClass)) {
classes[c] = primitiveToObjectMap.get(rawClass);
} else {
classes[c] = rawClass;
}
// comparator
if(Comparable.class.isAssignableFrom(classes[c])) comparators[c] = GlazedLists.comparableComparator();
else comparators[c] = null;
}
}
}
public BeanTableFormat(Class<E> beanClass, String[] propertyNames, String[] columnLabels) {
this(beanClass, propertyNames, columnLabels, new boolean[propertyNames.length]);
}
/**
* Loads the property descriptors which are used to invoke property
* access methods using the property names.
*/
protected void loadPropertyDescriptors(Class<E> beanClass) {
beanProperties = new BeanProperty[propertyNames.length];
for(int p = 0; p < propertyNames.length; p++) {
beanProperties[p] = new BeanProperty<E>(beanClass, propertyNames[p], true, editable[p]);
}
}
// TableFormat // // // // // // // // // // // // // // // // // // // //
/**
* The number of columns to display.
*/
public int getColumnCount() {
return columnLabels.length;
}
/**
* Gets the title of the specified column.
*/
public String getColumnName(int column) {
return columnLabels[column];
}
/**
* Gets the value of the specified field for the specified object. This
* is the value that will be passed to the editor and renderer for the
* column. If you have defined a custom renderer, you may choose to return
* simply the baseObject.
*/
public Object getColumnValue(E baseObject, int column) {
if(baseObject == null) return null;
// load the property descriptors on first request
if(beanProperties == null) loadPropertyDescriptors((Class<E>) baseObject.getClass());
// get the property
return beanProperties[column].get(baseObject);
}
// WritableTableFormat // // // // // // // // // // // // // // // // // //
/**
* For editing fields. This returns true if the specified Object in the
* specified column can be edited by the user.
*
* @param baseObject the Object to test as editable or not. This will be
* an element from the source list.
* @param column the column to test.
* @return true if the object and column are editable, false otherwise.
* @since 2004-August-27, as a replacement for isColumnEditable(int).
*/
public boolean isEditable(E baseObject, int column) {
return editable[column];
}
/**
* Sets the specified field of the base object to the edited value. When
* a column of a table is edited, this method is called so that the user
* can specify how to modify the base object for each column.
*
* @param baseObject the Object to be edited. This will be the original
* Object from the source list.
* @param editedValue the newly constructed value for the edited column
* @param column the column which has been edited
* @return the revised Object, or null if the revision shall be discarded.
* If not null, the EventTableModel will set() this revised value in
* the list and overwrite the previous value.
*/
public E setColumnValue(E baseObject, Object editedValue, int column) {
if(baseObject == null) return null;
// load the property descriptors on first request
if(beanProperties == null) loadPropertyDescriptors((Class<E>) baseObject.getClass());
// set the property
beanProperties[column].set(baseObject, editedValue);
// return the modified result
return baseObject;
}
// AdvancedTableFormat // // // // // // // // // // // // // // // // // //
/**
* Get the class of the specified column.
*/
public Class getColumnClass(int column) {
return classes[column];
}
/**
* Get the comparator for the specified column.
*/
public Comparator getColumnComparator(int column) {
return comparators[column];
}
}
|