java,静态方法在真实案例中发布。 TableModel实现

时间:2012-02-05 17:41:57

标签: java swing static-methods

我想实现一个TableModel,它将使我的现有数据结构能够由JTable显示。
假设我的数据结构是一个简单的 List< MyRow> ,其中MyRow是:

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)方法:columnsIndex&lt; columnCount。
即使List中没有行,也可能会询问此信息,因此没有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提供抽象超类。 这应该是显而易见的,但可以肯定:

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的具体实现的类型的引用。

如何解决这个问题,保持到目前为止所取得的良好封装水平?

1 个答案:

答案 0 :(得分:4)

您正在混合模型和视图概念。你的模型MyRow不应该知道它将如何表示,所以它不应该知道有多少列,它们包含什么等等...这就是你遇到这个问题的原因(使用静态方法来知道列数)。

更干净地执行此操作的一种方法是让TableModel返回列数,并通过调用MyRow类的成员来实现getValueAt。您是否看过默认实现(DefaultTableModel)。

现在我不明白为什么你需要覆盖静态方法(这是不可能的)。如果您需要为不同的对象提供不同的表模型,那么您可以考虑创建以相同方式相互继承的不同表模型。