Как не только удалить JPanel из JTabbedPane, но и изящно удалить экземпляр JPanel? - PullRequest
0 голосов
/ 21 апреля 2020

Эксперты, нужна помощь.

Я создал JFrame, скажем, в классе 'A' и добавил JTabbedPane с использованием среды IDE NetBeans, а также добавил первую JPanel в эту JTabbedPane. На этом JPanel у меня есть JCheckbox, который добавляет и удаляет новую вкладку (экземпляр JPanel), основываясь на событии check / unchecked. Добавляемая и удаляемая панель определяется в другом, скажем, классе «B», который расширяет JPanel. Эта JPanel имеет задачу таймера, которая выполняется с заданным интервалом c, получает некоторые данные из ресурса 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 ( это & это ), и было подтверждено, что, как только для ссылок установлено значение NULL, G C позаботится этого В этом случае я не уверен, как установить нулевую ссылку, так как я просто удаляю панель из JTabbedPane. Я следил за своим приложением в течение достаточно долгого времени, и я не видел, чтобы G C очищал его. Правильно ли я смотрю на это? Какой правильный и рекомендуемый способ удаления / аннулирования панели, удаленной из JTabbledPane?

Ответы [ 2 ]

1 голос
/ 21 апреля 2020

Существует несколько возможных способов решения этой проблемы. Одним из самых простых будет переопределить метод removeNotify для JPanel. Он вызывается, когда компонент удаляется из родительского контейнера.

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

Примечание: вместо этого вы можете cancel TimerTask, если Timer является общим, но вы необходимо сохранить ссылку на него при создании

0 голосов
/ 21 апреля 2020

Я не уверен, что следую за всем этим, но похоже, что вкладка, которую вы пытаетесь утилизировать, представлена ​​подклассом B JPanel, который содержит ссылку на таймер, и что свидетельство того, что таймер продолжает ли работать ваше свидетельство того, что B все еще существует?

Но если существование таймера зависит от этого экземпляра B, не будет ли что-то в инфраструктуре таймера иметь ссылку на B? Мне не менее понятно, почему вы не отлавливаете событие и не утилизируете класс таймера, вы не можете ожидать, что утилизирующий код сделает это за вас.

Кроме того, вы не можете просто следите за программой в течение определенного периода и решите, сделал ли G C то, что будет делать. Какие случаи это очищает, и как скоро и так далее, не полностью основано на времени. Те, с которыми я провел какое-то время, не запускаются до тех пор, пока программе не хватит памяти, для начала.

...