我想实现一个 TableModel,这将使我现有的数据结构能够通过 JTable 显示。
假设我的数据结构是一个简单的 List
public class MyRow {
String firstName;
String secondName;
}
我的想法是这个类在显示时“应该尽自己的职责”,所以我添加了以下方法,该方法简单地将每个字段映射到一个索引:
public Object getValueAt(int columnIndex) {
switch (columnIndex) {
case 0: return firstName;
case 1: return secondName;
default: return null;
}
}
此时,TableModel
实现将是:
public class MyModel extends AbstractTableModel {
ArrayList<MyRow> list = new ArrayList<MyRow>();
public int getRowCount() {return list.size();}
public int getColumnCount() {return 2;}
public Object getValueAt(int rowIndex, int columnIndex) {
return list.get(rowIndex).getValueAt(columnIndex);
}
}
很整洁,不是吗? :-)
好的,但是 return 2;
让我很烦恼。在这个“体系结构”中,我已将表示行的可解释性分配给 MyRow,因此应该由 MyRow 给出列数。这是因为它提供了与列数相关的 getValueAt(int columnIndex)
方法:columnsIndexList
中没有行,因此也没有 MyRow
实例,也可能会询问这条信息。因此添加到 MyRow 的方法应该是静态方法:
public class MyRow {
...
public static int getColumnCount() { return 2; }
...
MyModel 的 getColumnCount() 方法将进行相应的修改:
public int getColumnCount() {
//return 2; //No more this *Encapsulation Violation*
return MyRow.getColumnCount();
}
现在 MyRow 包含表示一行所需的所有数据。很容易证明:添加、删除或更改列只是修改 MyRow 的问题。
干净,不是吗? :-) :-)
问题是,使用静态方法,我无法为 MyRow 提供抽象父类(super class)。 这应该是显而易见的,但可以肯定的是:
public abstract class MyAbstractRow {
public static int getColumnCount() { return 0; }
}
然后
public class MyRow extends MyAbstractRow{
String firstName;
String secondName;
public static int getColumnCount() { return 2; }
}
然后我实现一个“通用”MyData,它使用 MyAbstractRow:
public int getColumnCount() {
//return 2; //No more this *Encapsulation Violation*
return MyAbstractRow.getColumnCount();
}
这是在静态类型上解决的(因此返回 0),因为 MyData 的 getColumnCount 甚至没有对我实际想要用作 MyAbstractRow 的具体实现的类型的引用。
如何解决这个问题,同时保持迄今为止所达到的良好封装水平?
最佳答案
您正在混合模型和 View 概念。您的模型 MyRow 不应该知道它将如何表示,因此它不应该知道有多少列、它们包含什么等等...这就是您遇到此问题的原因(使用静态方法来知道列数)。
一种更简洁的方法是让 TableModel 返回列数,并通过调用 MyRow 类的成员来实现 getValueAt。您查看过默认实现 (DefaultTableModel) 吗?
现在我不明白为什么你需要重写静态方法(这是不可能的)。如果您需要为相互继承的不同对象拥有不同的表模型,那么您可以考虑以相同的方式创建相互继承的不同表模型。
关于java,实际情况下的静态方法问题。表模型实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9151432/