1 /*
2 * Angkor Web Framework
3 *
4 * Distributable under LGPL license.
5 * See terms of license at gnu.org.
6 */
7
8 package com.tirsen.angkor.beans;
9
10 import com.tirsen.angkor.table.AbstractTableModel;
11 import com.tirsen.angkor.widget.ValueModel;
12
13 import java.beans.BeanInfo;
14 import java.beans.IntrospectionException;
15 import java.beans.Introspector;
16 import java.beans.PropertyDescriptor;
17 import java.io.Serializable;
18 import java.util.ArrayList;
19 import java.util.List;
20
21 public abstract class BeanTableModel extends AbstractTableModel
22 {
23 private Class rowClass;
24 private List columns;
25
26 public BeanTableModel()
27 {
28 }
29
30 public BeanTableModel(Class rowClass)
31 {
32 this.rowClass = rowClass;
33 }
34
35 public interface TableColumnModel extends Serializable
36 {
37 String getName();
38
39 ValueModel getValue(Object row);
40 }
41
42 private static class PropertyTableColumnModel implements TableColumnModel
43 {
44 private String name;
45 private PropertyDescriptor property;
46
47 public PropertyTableColumnModel(PropertyDescriptor property)
48 {
49 this.property = property;
50 }
51
52 public PropertyTableColumnModel(String name, PropertyDescriptor property)
53 {
54 this.name = name;
55 this.property = property;
56 }
57
58 public String getName()
59 {
60 return name == null ? property.getDisplayName() : name;
61 }
62
63 public ValueModel getValue(Object row)
64 {
65 return new PropertyValueModel(row, property);
66 }
67 }
68
69 /***
70 * Resets the columns.
71 */
72 public void resetColumns()
73 {
74 columns = null;
75 }
76
77 /***
78 * If the columns are not already created creates columns based on all the properties in the beans.
79 */
80 private void createDefaultColumns()
81 {
82 if (columns == null)
83 {
84 try
85 {
86 PropertyDescriptor[] properties = getProperties();
87 columns = new ArrayList(properties.length);
88 for (int i = 0; i < properties.length; i++)
89 {
90 PropertyDescriptor property = properties[i];
91 addColumn(new PropertyTableColumnModel(property));
92 }
93 }
94 catch (IntrospectionException e)
95 {
96 throw new RuntimeException(e.getMessage());
97 }
98 }
99 }
100
101 private PropertyDescriptor[] getProperties() throws IntrospectionException
102 {
103 Class beanClass = getRowClass();
104 BeanInfo beanInfo = Introspector.getBeanInfo(beanClass, Object.class);
105 PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors();
106 return properties;
107 }
108
109 protected Class getRowClass()
110 {
111 Class cls = rowClass;
112 if (cls == null && getRowCount() > 0) cls = getRow(0).getClass();
113 if (cls == null) cls = getRows().getClass().getComponentType();
114 if (cls == null) throw new IllegalStateException("Could not determine class of objects used for rows.");
115 return cls;
116 }
117
118 public void addColumn(TableColumnModel column)
119 {
120 columns.add(column);
121 }
122
123 public PropertyDescriptor findProperty(String property)
124 {
125 try
126 {
127 PropertyDescriptor[] properties = getProperties();
128 for (int i = 0; i < properties.length; i++)
129 {
130 PropertyDescriptor propertyDesc = properties[i];
131 if (propertyDesc.getName().equals(property)) return propertyDesc;
132 }
133 throw new IntrospectionException("No such property " + property);
134 }
135 catch (IntrospectionException e)
136 {
137 throw new RuntimeException(e.getMessage());
138 }
139 }
140
141 public void addColumn(String name, String property)
142 {
143 if (columns == null) columns = new ArrayList(1);
144 columns.add(new PropertyTableColumnModel(name, findProperty(property)));
145 }
146
147 public String getColumnName(int column)
148 {
149 return getColumn(column).getName();
150 }
151
152 public int getColumnCount()
153 {
154 createDefaultColumns();
155 return columns.size();
156 }
157
158 public ValueModel getValueAt(int row, int column)
159 {
160 return (getColumn(column)).getValue(getRow(row));
161 }
162
163 private TableColumnModel getColumn(int column)
164 {
165 createDefaultColumns();
166 return (TableColumnModel) columns.get(column);
167 }
168
169 /***
170 * Gets the value object for a specified row, also checks wheather row is within range specified by
171 * {@link #setRange(int,int)}.
172 * @throws IllegalArgumentException if <code>row</code> parameter is outside specified range.
173 */
174 public Object getRow(int row)
175 {
176 if (row < getStart() || row > getEnd())
177 {
178 throw new IllegalArgumentException("Tried to access row " + row +
179 " outside range (" + getStart() + ", " + getEnd() + ").");
180 }
181 return getRows().get(row);
182 }
183
184 protected abstract List getRows();
185 }
This page was automatically generated by Maven