diff --git a/designer-base/src/main/java/com/fr/common/listener/ManageDsListenerRegisterListener.java b/designer-base/src/main/java/com/fr/common/listener/ManageDsListenerRegisterListener.java new file mode 100644 index 000000000..6baa2e86b --- /dev/null +++ b/designer-base/src/main/java/com/fr/common/listener/ManageDsListenerRegisterListener.java @@ -0,0 +1,49 @@ +package com.fr.common.listener; + +import com.fr.design.data.DesignTableDataManager; +import javax.swing.event.AncestorEvent; +import javax.swing.event.AncestorListener; +import javax.swing.event.ChangeListener; + +/** + * 管理数据集相关监听的注册 + * + * 原本的监听生命周期注册与销毁: + * + * 创建时组件时进行注册,在模板关闭时进行销毁 + * 但是在模板未关闭的这段时间,如果不断的打开和关闭某些弹窗,次数达到一定程度,会导致出现大量内存占用,除非此时关闭模板 + * + * 改成以下模式: + * + * 当组件可见或者被添加到某个大组件 注册相关监听 + * 当组件不可见或者被移除时 立即移除相关监听 + * 及时清理无效监听,减少实时内存占用 + * + * + * @author hades + * @version 11.0 + * Created by hades on 2022/2/14 + */ +public class ManageDsListenerRegisterListener implements AncestorListener { + + private ChangeListener changeListener; + + public ManageDsListenerRegisterListener(ChangeListener changeListener) { + this.changeListener = changeListener; + } + + @Override + public void ancestorAdded(AncestorEvent event) { + DesignTableDataManager.addDsChangeListener(changeListener); + } + + @Override + public void ancestorRemoved(AncestorEvent event) { + DesignTableDataManager.removeDsChangeLister(changeListener); + } + + @Override + public void ancestorMoved(AncestorEvent event) { + // do nothing + } +} diff --git a/designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java b/designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java index f1758f068..8a57cca0b 100644 --- a/designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java +++ b/designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java @@ -172,23 +172,38 @@ public abstract class DesignTableDataManager { globalDsListeners.add(l); } + private static String getCurrentChangeListenerKey() { + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + String key = StringUtils.EMPTY; + if (template != null) { + key = template.getPath(); + } + return key; + } + /** * 添加模板数据集改变 监听事件. * * @param l ChangeListener监听器 */ public static void addDsChangeListener(ChangeListener l) { - JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - String key = StringUtils.EMPTY; - if (template != null) { - key = template.getPath(); - } + String key = getCurrentChangeListenerKey(); List dsListeners = dsListenersMap.get(key); if (dsListeners == null) { dsListeners = new ArrayList(); dsListenersMap.put(key, dsListeners); } - dsListeners.add(l); + if (!dsListeners.contains(l)) { + dsListeners.add(l); + } + } + + public static void removeDsChangeLister(ChangeListener l) { + String key = getCurrentChangeListenerKey(); + List dsListeners = dsListenersMap.get(key); + if (dsListeners != null) { + dsListeners.remove(l); + } } /** diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java index f65610526..6917f4c08 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java @@ -1,6 +1,7 @@ package com.fr.design.data.datapane; import com.fr.base.TableData; +import com.fr.common.listener.ManageDsListenerRegisterListener; import com.fr.concurrent.NamedThreadFactory; import com.fr.data.core.DataCoreUtils; import com.fr.data.core.db.DBUtils; @@ -648,12 +649,12 @@ public class ChoosePane extends BasicBeanPane implements Refresha */ @Override public void registerDSChangeListener() { - DesignTableDataManager.addDsChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - initDsNameComboBox(); - } - }); + this.addAncestorListener(new ManageDsListenerRegisterListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + initDsNameComboBox(); + } + })); } /** diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java index ebbdbf0f3..140b294bf 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java @@ -1,5 +1,6 @@ package com.fr.design.data.datapane; +import com.fr.common.listener.ManageDsListenerRegisterListener; import java.awt.Component; import java.awt.event.ItemEvent; import java.util.Iterator; @@ -148,7 +149,7 @@ public class TableDataComboBox extends UIComboBox implements Prepare4DataSourceC TableDataComboBox.this.refresh(DesignTableDataManager.getEditingTableDataSource()); } }; - DesignTableDataManager.addDsChangeListener(changeListener); + this.addAncestorListener(new ManageDsListenerRegisterListener(changeListener)); } public void registerGlobalDSChangeListener() { diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java index 6b75dff69..902347fb8 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java @@ -4,6 +4,7 @@ package com.fr.design.mainframe.chart; import com.fr.chart.chartattr.Chart; import com.fr.chart.chartattr.ChartCollection; import com.fr.chartx.attr.ChartProvider; +import com.fr.common.listener.ManageDsListenerRegisterListener; import com.fr.design.ChartTypeInterfaceManager; import com.fr.design.beans.FurtherBasicBeanPane; import com.fr.design.data.DesignTableDataManager; @@ -407,14 +408,14 @@ public class ChartEditPane extends BasicPane implements AttributeChange, Prepare * 数据集改变的事件监听 */ public void registerDSChangeListener() { - DesignTableDataManager.addDsChangeListener(new ChangeListener() { + this.addAncestorListener(new ManageDsListenerRegisterListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { AbstractChartAttrPane attrPane = paneList.get(tabsHeaderIconPane.getSelectedIndex()); if (attrPane.isShowing()) { attrPane.refreshChartDataPane(collection); } } - }); + })); } public boolean isInForm() {