如何使用单个 table 模型创建带有 POJO 的 JTable
how to create a JTable with POJOs with a single table model
我正在尝试创建一个 GUI 来显示数据库的内容。我正在为此使用 JTable。我想要一个采用 POJO 列表并最终采用列标题的构造函数。我还希望我的 JTable 能够 return 选定的 POJO(例如,当我双击一行时)。我真的需要为每个 POJO 创建一个 table 模型还是有更好的方法?
我搜索了一些类似的主题,但我没有找到任何对所有 POJO 使用单一 table 模型的答案,其中 none 个具有 return 是一个 POJO。
这是我的数据库 table 和 POJO 的描述:
数据库 tables:
- 学生(身份证、名字、姓氏、生日、grade_id、电话号码)
- 成绩(id,成绩)
- 作者(id,名字,姓氏,nationality_id)
- 国籍(id,国籍)
- 书籍(id,书名,author_id,student_id)
POJO:
- 成绩(int id, String grade)
- Student (int id, String firstname, String lastname, Grade grade)
- 作者(int id, String firstname, String lastname, Nationality 国籍)
- 国籍(int id, String nationality)
- Book (int id, String title, Author author, Student 学生)
我猜有人已经创建了一个由 bean getter 和 setter 支持的通用 TableModel
。尝试谷歌搜索 ReflectionTableModel
或 BeanTableModel
.
否则使用 reflection api
滚动您自己的 TableModel
会非常简单
查看 Row Table Model。它为 TableModel
方法提供一般支持。您将需要为 POJO 的特定字段实现几个方法。
或者您可以使用 Bean Table Model。它在您的 POJO 上使用反射来创建 TableModel
。它扩展了 RowTableModel
.
这是使用反射和注释的解决方案示例。
public class Worker {
@Updatable(false)
@Order(1)
@ColumnName("ID")
private int id;
@Updatable(true)
@Order(2)
@ColumnName("FIRST NAME")
private String firstName;
@Updatable(true)
@Order(3)
@ColumnName("LAST NAME")
private String lastName;
public Worker() {
}
public Worker(int id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
@Order(1)
public int getId() {
return id;
}
@Order(1)
public void setId(int id) {
this.id = id;
}
@Order(2)
public String getFirstName() {
return firstName;
}
@Order(2)
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@Order(3)
public String getLastName() {
return lastName;
}
@Order(3)
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
-
@Retention(RetentionPolicy.RUNTIME)
public @interface Order {
int value();
}
-
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ColumnName {
String value();
}
-
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Updatable {
boolean value();
}
-
public class ComparatorReflection<T extends AccessibleObject & Member> implements Comparator<T>{
@Override
public int compare(T o1, T o2) {
Order or1 = o1.getAnnotation(Order.class);
Order or2 = o2.getAnnotation(Order.class);
if (or1 != null && or2 != null && or1.value() - or2.value() != 0) {
return or1.value() - or2.value();
}
return o1.getName().compareTo(o2.getName());
}
}
-
public class ModelDAO extends AbstractTableModel {
private List<?> data;
public ModelDAO(List data) {
this.data = data;
}
@Override
public int getRowCount() {
return this.data.size();
}
@Override
public int getColumnCount() {
return data.get(0).getClass().getDeclaredFields().length;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
try {
Method[] methods = data.get(rowIndex).getClass().getDeclaredMethods();
Arrays.sort(methods, new ComparatorReflection<Method>());
return methods[2*columnIndex].invoke(data.get(rowIndex), null);
} catch (Exception ex) {
ex.printStackTrace();
}
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Class<?> getColumnClass(int columnIndex) {
Field[] fields = data.get(0).getClass().getDeclaredFields();
Arrays.sort(fields, new ComparatorReflection<Field>());
return fields[columnIndex].getType();
}
@Override
public String getColumnName(int column) {
Field[] fields = data.get(0).getClass().getDeclaredFields();
Arrays.sort(fields, new ComparatorReflection<Field>());
return fields[column].getAnnotation(ColumnName.class).value();
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
Field[] fields = data.get(rowIndex).getClass().getDeclaredFields();
Arrays.sort(fields, new ComparatorReflection<Field>());
return fields[columnIndex].getAnnotation(Updatable.class).value();
}
}
我正在尝试创建一个 GUI 来显示数据库的内容。我正在为此使用 JTable。我想要一个采用 POJO 列表并最终采用列标题的构造函数。我还希望我的 JTable 能够 return 选定的 POJO(例如,当我双击一行时)。我真的需要为每个 POJO 创建一个 table 模型还是有更好的方法?
我搜索了一些类似的主题,但我没有找到任何对所有 POJO 使用单一 table 模型的答案,其中 none 个具有 return 是一个 POJO。
这是我的数据库 table 和 POJO 的描述:
数据库 tables:
- 学生(身份证、名字、姓氏、生日、grade_id、电话号码)
- 成绩(id,成绩)
- 作者(id,名字,姓氏,nationality_id)
- 国籍(id,国籍)
- 书籍(id,书名,author_id,student_id)
POJO:
- 成绩(int id, String grade)
- Student (int id, String firstname, String lastname, Grade grade)
- 作者(int id, String firstname, String lastname, Nationality 国籍)
- 国籍(int id, String nationality)
- Book (int id, String title, Author author, Student 学生)
我猜有人已经创建了一个由 bean getter 和 setter 支持的通用 TableModel
。尝试谷歌搜索 ReflectionTableModel
或 BeanTableModel
.
否则使用 reflection api
滚动您自己的TableModel
会非常简单
查看 Row Table Model。它为 TableModel
方法提供一般支持。您将需要为 POJO 的特定字段实现几个方法。
或者您可以使用 Bean Table Model。它在您的 POJO 上使用反射来创建 TableModel
。它扩展了 RowTableModel
.
这是使用反射和注释的解决方案示例。
public class Worker {
@Updatable(false)
@Order(1)
@ColumnName("ID")
private int id;
@Updatable(true)
@Order(2)
@ColumnName("FIRST NAME")
private String firstName;
@Updatable(true)
@Order(3)
@ColumnName("LAST NAME")
private String lastName;
public Worker() {
}
public Worker(int id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
@Order(1)
public int getId() {
return id;
}
@Order(1)
public void setId(int id) {
this.id = id;
}
@Order(2)
public String getFirstName() {
return firstName;
}
@Order(2)
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@Order(3)
public String getLastName() {
return lastName;
}
@Order(3)
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
-
@Retention(RetentionPolicy.RUNTIME)
public @interface Order {
int value();
}
-
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ColumnName {
String value();
}
-
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Updatable {
boolean value();
}
-
public class ComparatorReflection<T extends AccessibleObject & Member> implements Comparator<T>{
@Override
public int compare(T o1, T o2) {
Order or1 = o1.getAnnotation(Order.class);
Order or2 = o2.getAnnotation(Order.class);
if (or1 != null && or2 != null && or1.value() - or2.value() != 0) {
return or1.value() - or2.value();
}
return o1.getName().compareTo(o2.getName());
}
}
-
public class ModelDAO extends AbstractTableModel {
private List<?> data;
public ModelDAO(List data) {
this.data = data;
}
@Override
public int getRowCount() {
return this.data.size();
}
@Override
public int getColumnCount() {
return data.get(0).getClass().getDeclaredFields().length;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
try {
Method[] methods = data.get(rowIndex).getClass().getDeclaredMethods();
Arrays.sort(methods, new ComparatorReflection<Method>());
return methods[2*columnIndex].invoke(data.get(rowIndex), null);
} catch (Exception ex) {
ex.printStackTrace();
}
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Class<?> getColumnClass(int columnIndex) {
Field[] fields = data.get(0).getClass().getDeclaredFields();
Arrays.sort(fields, new ComparatorReflection<Field>());
return fields[columnIndex].getType();
}
@Override
public String getColumnName(int column) {
Field[] fields = data.get(0).getClass().getDeclaredFields();
Arrays.sort(fields, new ComparatorReflection<Field>());
return fields[column].getAnnotation(ColumnName.class).value();
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
Field[] fields = data.get(rowIndex).getClass().getDeclaredFields();
Arrays.sort(fields, new ComparatorReflection<Field>());
return fields[columnIndex].getAnnotation(Updatable.class).value();
}
}