Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何不仅从JTabbedPane中删除JPanel,而且优雅地处理JPanel实例?_Java_Swing_Jpanel_Jtabbedpane - Fatal编程技术网

Java 如何不仅从JTabbedPane中删除JPanel,而且优雅地处理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主体中的内容,如下所

专家们,需要一些帮助

我在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的建议来解决这个问题。也谢谢你的帮助:)