java,实际情况下的静态方法问题。表模型实现

标签 java swing static-methods

我想实现一个 TableModel,这将使我现有的数据结构能够通过 JTable 显示。
假设我的数据结构是一个简单的 List,其中 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 即使 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 提供抽象父类(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/

相关文章:

java - Android Studio 构建不断崩溃(stableIds.txt 数据无效。(13))

java - 使 Guava CacheLoader 中的刷新条目无效

C# .NET 相当于 Java Swing Actions

java - 访问java类的方法的最佳方法是创建对象或使方法成为静态类型?

java - 处理一个不存在的 servlet 异常

java - BlazeDS vs GraniteDS - 2 年后

java - 如何在 JPanel 上绘制与代码相关的矩形作为对象(可以像 Photoshop 一样选择、删除等)

java - 我正在尝试制作一个显示元素列表的 JFrame,每个元素代表目录中的一个文件

swift - 将静态方法的引用传递给函数