专家,需要一些帮助。
我已经在类'A'中创建了JFrame,并使用NetBeans IDE添加了JTabbedPane,还向该JTabbedPane添加了第一个JPanel。在此JPanel上,我具有JCheckbox,该JCheckbox可以基于选中/未选中事件添加和删除新标签(JPanel的实例)。要添加和删除的面板在扩展JPanel的另一个“ B”类中定义。该JPanel具有一个计时器任务,该任务以特定的间隔运行,从REST资源获取一些数据并更新JPanel主体中的内容,如下所示:
private void refreshAgentUtilizationData() {
TimerTask updateAgentDetailsTask = new TimerTask() {
@Override
public void run() {
agentObj.updateData();
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
memChart.repaint();
System.out.println("This is from Agent monitor timer task...");
}
});
}
};
agentMonTimer.scheduleAtFixedRate(updateAgentDetailsTask, 0, master_pollingInterval);
}
执行的JCheckBox操作(在“ A”类中)如下,
先介绍一些细节:
AgentMon_ChartsUI
=扩展JPanel并添加到JTabbedPane的类,即类B
agentMonTabs
=驻留在说类A中的JTabbedPane
private void agentMonSwitchActionPerformed(java.awt.event.ActionEvent evt) {
if (agentMonSwitch.isSelected()) {
AgentMon_ChartsUI agentChartPane = new AgentMon_ChartsUI();
Icon agentIcon = new javax.swing.ImageIcon(getClass().getResource("/resources/abc.png"));
agentMonTabs.addTab("Agent runtime monitor", agentIcon, agentChartPane);
agentMonTabs.setSelectedIndex(agentMonTabs.indexOfTab("Agent runtime monitor"));
} else {
agentMonTabs.remove(agentMonTabs.indexOfTab("Agent runtime monitor"));
}
}
问题是:我无法找到优美的方式来处理JPanel实例,该实例在复选框的uncheck事件中已删除。取消选中该选项卡后,我可以看到该选项卡已被成功删除,并且看起来面板已经消失了,但是我可以看到System.out.println...
仍在计时器的作业中执行。这意味着Jcheckbox>取消选中仅会删除选项卡,但不会将其丢弃。
我在StackOverflow(this和this)上检查了其他问题,并确认一旦将引用设置为null,GC就会处理。在这种情况下,我不确定如何将引用设置为null,因为我只是从JTabbedPane中删除面板。我监视了我的应用程序很长时间,但没有看到GC清除它。 我看对了吗?处理/废除从JTabbledPane卸下的面板的正确和推荐方法是什么?
我不确定是否要遵循所有这些步骤,但是听起来像您要处理的选项卡由JPanel子类B表示,该子类B包含对计时器的引用,并且该计时器是您继续证明B仍然存在吗?
但是如果计时器的存在取决于B的实例,计时器基础结构中的某些内容是否会引用B?对我来说还不是最清楚的原因,为什么你也不捕获事件,也不丢弃计时器类,所以不能指望销毁代码为你做到这一点。
另外,您不能仅监视程序一段时间并确定GC是否已完成将要执行的操作。它清理哪些实例以及清理多长时间等等都不完全基于时间。我花了很多时间才开始运行,直到程序内存不足为止。