1

假设我有一个JDialog(称为BrushListDialog)的专门子类,其中我有一个JList. 该列表使用自定义列表模型(扩展DefaultListModel<String>)和自定义单元格渲染器(扩展DefaultListCellRenderer)。为了便于阅读,我将这些类嵌套在主类中。

通常,我会将这些类设为静态(我为单元格渲染器所做的),但列表模型类具有以下方法:

private boolean showRemoveConfirmDialog(Object elem) {
    int option = JOptionPane.showConfirmDialog(BrushListDialog.this,
            elem + " is a default brush type.\nDo you want to allow the removal of such entries?",
            "Remove", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
    if (option == JOptionPane.YES_OPTION) {
        TYPES.clear();
        return true;
    }
    return false;
}

如您所见,它依赖于顶级类的实例来确定JOptionPane的显示位置。BrushListDialog.this,当然,不能在静态上下文中调用,因此嵌套类不能是静态的。

我看到了三种处理方法(使用null第一个参数 inshowConfirmDialog不是一个选项):

  1. 保持单元格渲染器静态,但将列表模型设为内部类以便能够调用BrushListDialog.this.
  2. 将两个嵌套类设为静态,并通过列表模型的构造函数传递当前BrushListDialog实例。
  3. 使用 Swing 实用程序方法来遍历组件并找到一个实例BrushListDialog(在我看来这很 hacky)。

所以我问你:为了能够访问父对话框的实例而保持列表模型非静态值得吗?

两个嵌套类的源代码

4

2 回答 2

1

我个人不会认为需要将类重构为非静态的——我们不是在谈论巨大的开销,只是在实践中的一个引用。鉴于此,它归结为更具可读性和可维护性的选项;我认为将代码保持原样最好属于该类别。

也就是说,如果你真的想让它成为静态的,我会选择你在第一个那里呈现的第二个选项。

您添加的第三个听起来很糟糕 - 绝对远离那个。

于 2012-12-10T12:39:37.060 回答
1

就 JVM 而言,选项 (1) 和 (2) 通常是相同的 - Java 编译器隐式创建对父类的引用和适当的构造函数。

我会根据您是否需要在父类之外使用该类来决定静态与嵌套。如果不是,则使用嵌套类来避免必须显式编写父参考代码 - 但要注意由不正确的访问说明符创建的隐式访问委托方法。

选项(3)听起来像一个非常脆弱的黑客,我会不惜一切代价避免......

于 2012-12-10T12:44:15.027 回答