Java Swing - JTable Lazy Pagination with JPA backend and @DisplayAs annotation to map columns/rows via reflection [Updated: Feb 3, 2018, Created: Feb 2, 2018] |
|
||
This example is an improvement of the last example. We are going to use JPA as backend to load pagination data lazily along with an annotation based approach to map columns of the TableModel via reflection. This is merger of the last example and this example. In the example, we just need to use Main classpublic class PaginationExampleMain { public static void main(String[] args) { JFrame frame = createFrame(); ObjectTableModel<Employee> objectDataModel = new DisplayableObjectTableModel<>(Employee.class); JTable table = new JTable(objectDataModel); table.setAutoCreateRowSorter(true); PaginationDataProvider<Employee> dataProvider = createDataProvider(objectDataModel); PaginatedTableDecorator<Employee> paginatedDecorator = PaginatedTableDecorator.decorate(table, dataProvider, new int[]{5, 10, 20, 50, 75, 100}, 10); frame.add(paginatedDecorator.getContentPanel()); frame.setLocationRelativeTo(null); frame.setVisible(true); } private static PaginationDataProvider<Employee> createDataProvider( ObjectTableModel<Employee> objectDataModel) { return new EmployeeLazyDataProvider(objectDataModel); } private static JFrame createFrame() { JFrame frame = new JFrame("JTable Pagination example"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(new Dimension(600, 300)); return frame; } } DisplayableObjectTableModelThis class is same as from this example: 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; } } The pagination decoratorThere's no change with the decorator from the previous two examples. PaginationDataProvider implementationThere's no change with the data provider from the last example. The JPA entityOther than JPA annotations, we are also going to use our @DisplayAs annotation in our entity @Entity public class Employee { @Id @SequenceGenerator(name = "eSGen", sequenceName = "employeeSeq", initialValue = 50) @GeneratedValue(generator = "eSGen") private long id; private String name; private String phoneNumber; private String address; @DisplayAs(value = "Id", index = 0) public long getId() { return id; } public void setId(long id) { this.id = id; } @DisplayAs(value = "Employee Name", index = 1) public String getName() { return name; } public void setName(String name) { this.name = name; } @DisplayAs(value = "Work Phone", index = 2) public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } @DisplayAs(value = "Address", index = 3) public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } } Output![]() Example ProjectDependencies and Technologies Used:
|
|
||
|
|||
|