【发布时间】:2014-09-29 20:59:55
【问题描述】:
我制作了一个包含 JButton 的 JFrame(称为 J1)。单击该按钮时,将打开一个新的 JFrame(称为 J2)。
J1 也有一个 ArrayList,其中包含 J2,以及所有其他打开的 Jframe。
J2 设置为 DISPOSE_ON_CLOSED
我为J2 设置了一个 windowClosed() 方法。为了测试,我在循环的 JFrame 中抛出了ArrayList,直到我到达刚刚关闭的当前J2,令人惊讶的是,当我执行J2.setVisisble(true) 时,J2 窗口返回!
我还检查了任务管理器,看到虽然打开一个新的J2,会使整个程序消耗更多的内存,关闭每个J2在任务管理器上并没有太大的区别,它没有看起来没有任何内存被释放。看起来内存消耗在几秒钟后恢复“正常”,所以我怀疑这与J2有什么直接关系。
每次启动新的J2 时,我都尝试打印(System.out.print)所有ArrayList 内容,在打开一个窗口、关闭它并打开一个新窗口后,我收到以下消息:
home.ATMmachine[frame0,252,198,620x420,invalid,hidden,layout=java.awt.BorderLayout,title=ATM Machine No.1,resizable,normal,defaultCloseOperation=DISPOSE_ON_CLOSE,rootPane=javax.swing.JRootPane[,9,38,602x373,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]
这意味着J2 没有被完全删除!
JFrame dispose() 方法应该是
释放此 Window、其子组件及其所有子组件使用的所有本机屏幕资源。也就是说,这些组件的资源将被销毁,它们消耗的任何内存都将返回给操作系统,并且它们将被标记为不可显示。
我是不是错了,该框架将在一段时间后被删除。
如果不是,那么我怎样才能删除框架以使引用它就像引用 null 一样?
【问题讨论】:
-
"closing each J2 doesn't show much difference on the Task Manager,..."-- 可能是因为 GC'ing 仅在需要时发生,因此当您的对象被标记为 GC'ing 时,它可能尚未被收集,因为没有必要。附带说明一下——为什么是所有的 JFrame?我用过的大多数向你抛出大量窗口的程序似乎都很烦人,我想这就是为什么我通常只看到新手程序员以这种方式创建它们的原因。为什么不使用 CardLayout 交换视图? -
"J2.setVisisble(true)"-- 这并不奇怪。调用dispose()释放资源。调用setVisible(true)会重新创建和重新使用资源。如果您可以再次将其设置为可见,那么您仍然有对该对象的引用,因此不会发生 GC'ing。 -
"This means that the J2 wasn't completely deleted!"-- 您不想将对象与资源混淆,这正是您在这里所做的。您已经维护了对该对象的引用(否则 println 无法完成),因此它当然存在并且将一直存在,直到引用不再存在(您无法打印任何内容),并且因为它继续存在当然打印出来会返回你看到的。 -
说得很好......但是关于新手的事情,有时您需要一个新框架,以便在需要完成另一个任务的同时仍然可以看到第一个任务。就像实时摄像头监控应用程序,以及另一个用于录制的 JFrame。虽然我同意它很烦人,尤其是任务栏中显示的图标
-
@vlatkozelka:不,你错了。如果绝对需要,新窗口应该是一个对话框窗口,例如 JDialog,而不是 JFrame。您不希望在系统任务栏上出现另一个带有图标的独立程序,对吗?并且新窗口是主窗口的子窗口,因此它应该是一个对话框,根据需要可以是模态的也可以是非模态的。