我正在使用NetBeans的GUI Designer来创建一些JDialog
,然后我从我自己的EditorDialog
类中继承它。
在进一步讨论之前,请考虑以下示例代码:
class MyDialog extends EditorDialog {
private Color someVariableThatTheGuiNeeds = new Color(0,50,100);
public MyDialog() {
super(true);
}
//<auto-generated>
private void initComponents() { //note this is private!
//...
}
//</auto-generated>
}
abstract class EditorDialog extends JDialog {
public EditorDialog() {
super(null,true);
}
public EditorDialog(boolean stuffNeedsDone) {
super(null,true);
//initComponents();
doStuffAfterGuiInitialized();
}
}
问题是,我不能从我的超类中调用initComponents()
,因为它是私有的。
为了解决这个问题,我尝试了一种解决方法:
//in EditorDialog
public EditorDialog(boolean stuffNeedsDone) {
super(null,true);
workaround();
doStuffAfterGuiInitialized();
}
protected abstract void workaround();
//in MyDialog
@Override
protected void workaround() {
initComponents();
}
当然,这不起作用,因为someVariableThatTheGuiNeeds
由于初始化的发生方式被调用initComponents()
时未初始化:
new MyDialog()
super(this)
EditorDialog(boolean)
被调用
super(null,true)
被调用,JDialog
做事EditorDialog
的实例变量已初始化workaround()
initComponents()
doSomethingWith(someVariableThatTheGuiNeeds)
- &gt; NullPointerException 因为someVariableThatTheGuiNeeds
尚未初始化someVariableThatTheGuiNeeds
已初始化此外,我无法在initComponents()
中创建非私有摘要EditorDialog
,因为覆盖时的可见性只会变得更加公开。
那么,我怎样才能解决这个问题,而不是太过于苛刻?
(如果您不熟悉NetBeans,我无法编辑自动生成的代码,并且没有选项(我可以找到)来更改initComponents()
方法上的访问修饰符。
答案 0 :(得分:1)
在任何情况下,您的构造函数都不应该调用非private
方法。如果在创建对话框后需要对其进行初始化,则可以创建一个init()
方法,该方法应在构造函数完成后调用。
注意,方法名称doStuffAfterGuiInitialized()
表示有点误解。在构造函数完成之后,GUI或甚至实例都不会完全初始化。
答案 1 :(得分:0)
这是java中常见的问题。 Instanciation不是子类化的朋友。
许多人使用间接解决方案:一旦对象完全构建,就调用init()方法。
这通常是通过工厂自动完成的。 所有注入框架(如Spring)都会定期执行此操作。