Java 如何不仅从JTabbedPane中删除JPanel,而且优雅地处理JPanel实例?
专家们,需要一些帮助 我在say类“A”中创建了JFrame,并使用NetBeans IDE添加了JTabbedPane,还向这个JTabbedPane添加了第一个JPanel。在这个JPanel上,我有一个JCheckbox,它根据checked/unchecked事件添加和删除新选项卡(JPanel的实例)。正在添加和删除的面板在另一个扩展JPanel的类“B”中定义。此JPanel有一个计时器任务,它在特定的时间间隔内运行,从REST资源获取一些数据,并更新JPanel主体中的内容,如下所示:Java 如何不仅从JTabbedPane中删除JPanel,而且优雅地处理JPanel实例?,java,swing,jpanel,jtabbedpane,Java,Swing,Jpanel,Jtabbedpane,专家们,需要一些帮助 我在say类“A”中创建了JFrame,并使用NetBeans IDE添加了JTabbedPane,还向这个JTabbedPane添加了第一个JPanel。在这个JPanel上,我有一个JCheckbox,它根据checked/unchecked事件添加和删除新选项卡(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\u ChartsUI
=扩展JPanel并添加到JTabbedPane的类,即B类
agentMonTabs
=JTabbedPane,驻留在类A中
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实例,该实例在checkbox的uncheck事件中被删除。当我取消选中它时,我可以看到选项卡正在被成功删除,看起来面板现在不见了,但我可以看到System.out.println…
仍在计时器的作业中执行。这意味着Jcheckbox>Uncheck只会删除该选项卡,但不会处理它
我检查了StackOverflow(&)的其他问题,并确认一旦引用设置为null,GC将处理它。我不确定在这种情况下,如何将引用设置为null,因为我只是从JTabbedPane中删除面板。我监控了我的应用程序很长一段时间,但我没有看到GC清除它我看得对吗?处理/取消从JTabblePane中删除的面板的正确方法和推荐方法是什么?我不确定我是否了解所有这些,但听起来您试图处理的选项卡是由JPanel子类B表示的,该子类包含对计时器的引用,计时器继续运行的证据就是B仍然存在的证据 但是,如果计时器的存在依赖于B的实例,那么计时器基础结构中的某些东西不会引用B吗?我一点也不清楚为什么不捕获事件并处理timer类,您不能期望dispose代码为您这样做
此外,您不能只监视程序一段时间,然后决定GC是否已经执行了它将要执行的任何操作。它清理的实例以及清理的时间等等都不完全是基于时间的。我花了很多时间处理的那些程序在内存不足时才会运行。有很多可能的方法可以解决这个问题。最简单的方法之一是重写
JPanel
的removeNotify
方法。当组件从其父容器中移除时,将调用此函数
@Override
public void removeNotify() {
super.removeNotify()
agentMonTimer.cancel();
agentMonTimer.purge();
agentMonTimer = nil;
}
注意:如果
计时器
是共享的,您可以取消
计时器任务,但是您需要在创建它时维护对它的引用或者为B
提供某种dispose
方法,该a
可以调用,这有点混乱,因为您需要将选项卡的结果强制转换为B
或覆盖B
的removeNotify
,这将告诉您何时将组件从其父容器中移除,别忘了先调用它的super。另一个想法可能是为计时器(链接到面板)提供一个单独的控制器,因此,当您移除UI面板时,您可以指示控制器也处理相关的TimerTank you@MadProgrammer!removeNotify()被证明是救星。我正在针对我的需求编写类似JVIsualVM的资源监视器,最终用户将添加/删除面板负载。在你的帮助下,我至少可以轻松地知道没有人在后台占用资源,谢谢!谢谢你的意见。计时器任务中引用的方法大多是void(),只更新一些图表/字段,因此它们并不真正了解父容器的操作。我可以用@MadProgrammer的建议来解决这个问题。也谢谢你的帮助:)