java - 如何不仅从 JTabbedPane 中删除 JPanel,而且还优雅地处置 JPanel 实例?

标签 java swing jpanel jtabbedpane

专家,需要帮助。

我已经在“A”类中创建了 JFrame,并使用 NetBeans IDE 添加了 JTabbedPane,还向该 JTabbedPane 添加了第一个 JPanel。在此 JPanel 上,我有 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 = 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 实例,该实例在复选框的取消选中事件中被删除。当我取消选中它时,我可以看到该选项卡已成功删除,并且看起来面板现在已经消失了,但我可以看到 System.out.println... 仍在执行中计时器的工作。这意味着 Jcheckbox > Uncheck 只是删除选项卡,但不会释放它。

我检查了 StackOverflow 上的其他问题( thisthis ),并确认一旦引用设置为 null,GC 就会处理它。我不确定在这种情况下,应该如何将引用设置为 null,因为我只是从 JTabbedPane 中删除面板。我监控我的应用程序很长一段时间,但没有看到 GC 清除它。 我是否正确地看待它?处理/取消从 JTabbledPane 中删除的面板的正确和推荐方法是什么?

最佳答案

您可以采用多种方法来处理此问题。最简单的方法之一是重写 JPanelremoveNotify 方法。当组件从其父容器中删除时,就会调用此函数。

@Override
public void removeNotify() {
    super.removeNotify()
    agentMonTimer.cancel();
    agentMonTimer.purge();
    agentMonTimer = nil;
}

注意:如果 Timer 是共享的,您可以取消 TimerTask,但您需要维护一个引用当你创建它时它

关于java - 如何不仅从 JTabbedPane 中删除 JPanel,而且还优雅地处置 JPanel 实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61332840/

相关文章:

java - 如何将我的 JMenuBar 移动到 Mac OS X 上的屏幕菜单栏?

java - 添加一些图片到 BufferdImage 然后保存

java - 子类中的 JPanel 未正确添加到驱动程序 JFrame

javascript - 如何将音频 blob 从 javascript 发送到 java spring 服务器?

java - Spring @WithMockUser 和 request.IsUserInRole()

java - 如何使JTree选择模型只允许兄弟选择?

java - 如何获取 JFrame 中的所有元素?

Java Swing : components not added to JPanel with JScrollPane

java - 通过c3p0在mysql中查询超时

java - System.out.println 和 System.err.println 乱序