调用dispose方法后访问模态对话框变量

时间:2012-04-07 17:55:32

标签: java swing nullpointerexception modal-dialog dispose

情况:主窗体调用带有文本框的模态jDialog,其中参数由用户填写以创建或修改某个类的实例,称之为ClassA。

当对话框需要修改现有实例时,它将作为参数在构造函数中传递。否则,jDialog将创建一个新的ClassA实例。

问题:mainform需要访问那个新实例,我认为将整个主窗体作为参数传递是不洁净的代码,让对话框通过方法调用将新实例推入其中,因为这样一来完全可重用的独立对话框只能用于需要某个类名和方法来接收新实例的单个主窗体。

通过调用getClassAInstance()方法(在修改现有实例时也可以调用),使主窗体从单击OK按钮后从jdialog获取新实例更合乎逻辑。在所讨论的jdialog的新实例上的“setVisible(true)”方法之后调用该方法。出现对话框,主窗体的线程将休眠,直到对话框关闭(因为它是模态的)。 OK按钮调用jDialog的dispose()方法,然后下一个语句是mainform对jDialog的getClassAInstance()调用。

代码中的内容相同..

ClassAInstanceMakerDialog imd = new ClassAInstanceMakerDialog(this, true);
imd.setVisible(true);
//imd.dispose(); after OK button click
System.out.println(imd.getClassAInstance()); //return a new ClassA instance

//output: whatever ClassA.toString() should return, works fine

问题:我已经尝试过,它似乎工作得非常好。但是,它是一个很好的代码吗?是否存在getClassAInstance()方法返回“null”的危险,因为垃圾收集器在处理jDialog之后以及主表单完成调用之前收集了ClassA实例?

如果我不清楚,请原谅我,我不是母语为英语的人。如果你想看一些代码,请告诉我......

3 个答案:

答案 0 :(得分:2)

我认为访问包含ClassA实例的对话框实例的成员变量是完全合法的,对话框实例在超出范围之前不会被垃圾收集,而不仅仅是因为你调用了dispose。

我稍微倾向于使用

签名定义事件处理程序接口的解决方案

someThingHappened(ClassA toThisObject),使您的mainform或任何可能感兴趣的ClassA事物实现该接口,使得可以在使对话框可见之前添加侦听器。

这样,你可以放松对话框和主窗体之间的耦合。

答案 1 :(得分:1)

我不认为dispose()为垃圾收集设置JDialog,而只是释放资源。该对话框仍可按Window API重复使用(因为JDialog从Window继承此方法):

  

释放此Window,其子组件及其所有子组件使用的所有本机屏幕资源。也就是说,这些组件的资源将被销毁,它们使用的任何内存都将返回给操作系统,并且它们将被标记为不可显示。

     

通过随后调用pack或show重建本机资源,可以再次显示Window及其子组件。重新创建的窗口及其子组件的状态将与窗口处置点处的这些对象的状态相同(不考虑这些操作之间的其他修改)。

     

注意:当Java虚拟机(VM)中的最后一个可显示窗口被丢弃时,VM可能会终止。有关详细信息,请参阅AWT线程问题。

只要存在对JDialog对象的有效可到达引用,它就不会被垃圾回收。我认为处理对话框的成本是你的代码需要花费(非常)时间来重新创建资源。

答案 2 :(得分:1)

IDisposable被调用之后,可以使用Dispose包含属性或方法来返回有关Dispose被调用之前发生的事情的信息,这是完全合理和恰当的。不应盲目地执行规则,即被处置对象的任何和所有方法都应抛出ObjectDisposedException,而应考虑哪些方法和属性对已处置对象有意义或无意义。尝试访问已处置的对象应优先抛出ObjectDisposedException 以重新获取已释放的资源或让出现因处置而导致的其他异常。如果方法或属性访问可以在没有任何已释放资源的情况下成功,则通常应该允许这样做。