This is an improvement of the last example. In the following example we will extend TableModel and map rows/columns based on JavaBean properties of the provided object and Java reflection. We will also use a new annotation DisplayAs that will be used to specify various column properties such as 'display name' and 'index'.
Creating the TableModel
public abstract class ObjectTableModel<T> extends AbstractTableModel {
private List<T> objectRows = new ArrayList<>();
public List<T> getObjectRows() {
return objectRows;
}
public void setObjectRows(List<T> objectRows) {
this.objectRows = objectRows;
}
@Override
public int getRowCount() {
return objectRows.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
T t = objectRows.get(rowIndex);
return getValueAt(t, columnIndex);
}
public abstract Object getValueAt(T t, int columnIndex);
@Override
public abstract String getColumnName(int column);
public abstract String getFieldName(int column);
}
public class DisplayableObjectTableModel<T> extends ObjectTableModel<T> {
private Map<Integer, ColumnInfo> columnInfoMap;
public DisplayableObjectTableModel(Class<T> tClass) {
init(tClass);
}
private void init(Class<T> tClass) {
try {
BeanInfo beanInfo = Introspector.getBeanInfo(tClass);
this.columnInfoMap = new HashMap<>();
for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
Method m = pd.getReadMethod();
DisplayAs displayAs = m.getAnnotation(DisplayAs.class);
if (displayAs == null) {
continue;
}
ColumnInfo columnInfo = new ColumnInfo();
columnInfo.displayName = displayAs.value();
columnInfo.index = displayAs.index();
columnInfo.method = m;
columnInfo.propertyName = pd.getName();
columnInfoMap.put(columnInfo.index, columnInfo);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public Object getValueAt(T t, int columnIndex) {
try {
return columnInfoMap.get(columnIndex)
.method.invoke(t);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public int getColumnCount() {
return columnInfoMap.size();
}
@Override
public String getColumnName(int column) {
ColumnInfo columnInfo = columnInfoMap.get(column);
if (columnInfo == null) {
throw new RuntimeException("No column found for index " + column);
}
return columnInfo.displayName;
}
@Override
public String getFieldName(int column) {
ColumnInfo columnInfo = columnInfoMap.get(column);
return columnInfo.propertyName;
}
public Class<?> getColumnClass(int columnIndex) {
ColumnInfo columnInfo = columnInfoMap.get(columnIndex);
return columnInfo.method.getReturnType();
}
private static class ColumnInfo {
private Method method;
private int index;
private String displayName;
public String propertyName;
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DisplayAs {
String value();
int index();
}
The Example Bean
public class Employee {
private String name;
private String dept;
private String phone;
private String cellPhone;
@DisplayAs(value = "Employee Name", index = 1)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@DisplayAs(value = "Department", index = 0)
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
@DisplayAs(value = "Work Phone", index = 2)
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@DisplayAs(value = "Cell Phone", index = 3)
public String getCellPhone() {
return cellPhone;
}
public void setCellPhone(String cellPhone) {
this.cellPhone = cellPhone;
}
}
Main class
public class ExampleMain {
public static void main(String[] args) {
JFrame frame = createFrame();
ObjectTableModel<Employee> tableModel = new DisplayableObjectTableModel<>(Employee.class);
tableModel.setObjectRows(getEmployees());
JTable table = new JTable(tableModel);
JScrollPane pane = new JScrollPane(table);
frame.add(pane);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static JFrame createFrame() {
JFrame frame = new JFrame("JTable example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(600, 300));
return frame;
}
public static List<Employee> getEmployees() {
final List<Employee> list = new ArrayList<>();
for (int i = 1; i <= 30; i++) {
Employee e = new Employee();
e.setName("name" + i);
e.setPhone("phone" + i);
e.setDept("dept" + i);
e.setCellPhone("cell" + i);
list.add(e);
}
return list;
}
}
Output
Example ProjectDependencies and Technologies Used:
|