1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package ohos.devtools.views.layout.chartview.memory; 17 18 import com.intellij.openapi.ui.JBPopupMenu; 19 import com.intellij.ui.components.JBCheckBox; 20 import com.intellij.ui.components.JBLabel; 21 import com.intellij.ui.components.JBPanel; 22 import ohos.devtools.datasources.utils.monitorconfig.service.MonitorConfigManager; 23 import ohos.devtools.datasources.utils.profilerlog.ProfilerLogManager; 24 import ohos.devtools.views.common.UtConstant; 25 import ohos.devtools.views.layout.chartview.MonitorItemDetail; 26 import ohos.devtools.views.layout.chartview.observer.MemoryChartObserver; 27 import org.apache.logging.log4j.LogManager; 28 import org.apache.logging.log4j.Logger; 29 30 import javax.swing.AbstractButton; 31 import java.awt.Dimension; 32 import java.awt.FlowLayout; 33 import java.awt.event.MouseEvent; 34 import java.util.ArrayList; 35 import java.util.HashMap; 36 import java.util.LinkedList; 37 import java.util.List; 38 import java.util.Map; 39 import java.util.stream.Collectors; 40 41 /** 42 * MemoryPopupMenu 43 * 44 * @since 2021/10/25 45 */ 46 class MemoryItemPopupMenu { 47 private static final Logger LOGGER = LogManager.getLogger(MemoryItemPopupMenu.class); 48 private static final int CHECK_BOX_AMOUNT = 6; 49 private static final int H_GAP = 15; 50 private static final int V_GAP = 13; 51 private static final int ITEM_WIDTH = 140; 52 private static final int ITEM_HEIGHT = 20; 53 private static final int MEMORY_ITEM_PANEL_WIDTH = 160; 54 private static final int MEMORY_ITEM_PANEL_HEIGHT = 275; 55 private static final int POPUP_OFFSET = 15; 56 private static final String MEMORY_NAME = "Memory"; 57 58 private final long sessionId; 59 private final MemoryChartObserver chartObserver; 60 private final JBPopupMenu popupMenu = new JBPopupMenu(); 61 private final JBLabel memoryLabel = new JBLabel(MEMORY_NAME); 62 private final JBCheckBox checkBoxSelectAll = new JBCheckBox("Select all"); 63 private final JBCheckBox checkBoxMemoryJava = new JBCheckBox(MonitorItemDetail.MEM_JAVA.getName()); 64 private final JBCheckBox checkBoxGpuMemoryNative = new JBCheckBox(MonitorItemDetail.MEM_NATIVE.getName()); 65 private final JBCheckBox checkBoxGraphics = new JBCheckBox(MonitorItemDetail.MEM_GRAPHICS.getName()); 66 private final JBCheckBox checkBoxStack = new JBCheckBox(MonitorItemDetail.MEM_STACK.getName()); 67 private final JBCheckBox checkBoxCode = new JBCheckBox(MonitorItemDetail.MEM_CODE.getName()); 68 private final JBCheckBox checkBoxOthers = new JBCheckBox(MonitorItemDetail.MEM_OTHERS.getName()); 69 private final ArrayList<JBCheckBox> checkBoxes = new ArrayList<>(); 70 private Map<String, LinkedList<String>> configMap; 71 72 /** 73 * MemoryPopupMenu constructor 74 * 75 * @param sessionId sessionId 76 * @param chartObserver MemoryChartObserver 77 */ MemoryItemPopupMenu(long sessionId, MemoryChartObserver chartObserver)78 MemoryItemPopupMenu(long sessionId, MemoryChartObserver chartObserver) { 79 this.sessionId = sessionId; 80 this.chartObserver = chartObserver; 81 initCheckBoxes(); 82 initCheckItems(); 83 initSelectedItems(); 84 initListener(); 85 } 86 initCheckBoxes()87 private void initCheckBoxes() { 88 if (ProfilerLogManager.isInfoEnabled()) { 89 LOGGER.info("initCheckBoxes"); 90 } 91 checkBoxSelectAll.setSelected(true); 92 checkBoxSelectAll.setEnabled(false); 93 checkBoxes.add(checkBoxMemoryJava); 94 checkBoxes.add(checkBoxGpuMemoryNative); 95 checkBoxGpuMemoryNative.setName(UtConstant.UT_MEMORY_ITEM_POPUP_NATIVE); 96 checkBoxes.add(checkBoxGraphics); 97 checkBoxStack.setName(UtConstant.UT_MEMORY_ITEM_POPUP_STACK); 98 checkBoxes.add(checkBoxStack); 99 checkBoxes.add(checkBoxCode); 100 checkBoxes.add(checkBoxOthers); 101 } 102 initCheckItems()103 private void initCheckItems() { 104 if (ProfilerLogManager.isInfoEnabled()) { 105 LOGGER.info("initCheckItems"); 106 } 107 JBPanel checkItemPanel = new JBPanel(new FlowLayout(FlowLayout.LEADING, H_GAP, V_GAP)); 108 checkItemPanel.add(memoryLabel); 109 memoryLabel.setPreferredSize(new Dimension(ITEM_WIDTH, ITEM_HEIGHT)); 110 checkBoxSelectAll.setPreferredSize(new Dimension(ITEM_WIDTH, ITEM_HEIGHT)); 111 checkItemPanel.add(checkBoxSelectAll); 112 for (JBCheckBox checkBox : checkBoxes) { 113 checkBox.setPreferredSize(new Dimension(ITEM_WIDTH, ITEM_HEIGHT)); 114 checkItemPanel.add(checkBox); 115 } 116 checkItemPanel.setPreferredSize(new Dimension(MEMORY_ITEM_PANEL_WIDTH, MEMORY_ITEM_PANEL_HEIGHT)); 117 popupMenu.add(checkItemPanel); 118 } 119 initSelectedItems()120 private void initSelectedItems() { 121 if (ProfilerLogManager.isInfoEnabled()) { 122 LOGGER.info("initSelectedItems"); 123 } 124 configMap = MonitorConfigManager.DATA_MAP.get(sessionId); 125 if (configMap == null || configMap.get(MEMORY_NAME) == null) { 126 configMap = initFullItems(); 127 MonitorConfigManager.DATA_MAP.put(sessionId, configMap); 128 } 129 130 for (String str : configMap.get(MEMORY_NAME)) { 131 for (JBCheckBox jCheckBox : checkBoxes) { 132 if (jCheckBox.getText().equals(str)) { 133 jCheckBox.setSelected(true); 134 } 135 } 136 } 137 } 138 initFullItems()139 private Map<String, LinkedList<String>> initFullItems() { 140 if (ProfilerLogManager.isInfoEnabled()) { 141 LOGGER.info("initFullItems"); 142 } 143 LinkedList<String> items = new LinkedList<>(); 144 items.add(MonitorItemDetail.MEM_JAVA.getName()); 145 items.add(MonitorItemDetail.MEM_NATIVE.getName()); 146 items.add(MonitorItemDetail.MEM_GRAPHICS.getName()); 147 items.add(MonitorItemDetail.MEM_STACK.getName()); 148 items.add(MonitorItemDetail.MEM_CODE.getName()); 149 items.add(MonitorItemDetail.MEM_OTHERS.getName()); 150 Map<String, LinkedList<String>> memoryMap = new HashMap<>(); 151 memoryMap.put(MEMORY_NAME, items); 152 return memoryMap; 153 } 154 initListener()155 private void initListener() { 156 checkBoxSelectAll.addItemListener(event -> { 157 if (checkBoxSelectAll.isSelected()) { 158 for (JBCheckBox checkBox : checkBoxes) { 159 checkBox.setSelected(true); 160 } 161 } 162 }); 163 memoryAddItemListener(checkBoxMemoryJava); 164 memoryAddItemListener(checkBoxGpuMemoryNative); 165 memoryAddItemListener(checkBoxGraphics); 166 memoryAddItemListener(checkBoxStack); 167 memoryAddItemListener(checkBoxCode); 168 memoryAddItemListener(checkBoxOthers); 169 } 170 memoryAddItemListener(JBCheckBox checkBox)171 private void memoryAddItemListener(JBCheckBox checkBox) { 172 checkBox.addItemListener(event -> filterItemList()); 173 } 174 filterItemList()175 private void filterItemList() { 176 if (ProfilerLogManager.isInfoEnabled()) { 177 LOGGER.info("filterItemList"); 178 } 179 List<JBCheckBox> selectedList = 180 checkBoxes.stream().filter(AbstractButton::isSelected).collect(Collectors.toList()); 181 // Increase the judgment of the selected number of Check Boxes 182 if (selectedList.size() < CHECK_BOX_AMOUNT) { 183 // Select All uncheck the state and set it to non-clickable state 184 checkBoxSelectAll.setSelected(false); 185 checkBoxSelectAll.setEnabled(true); 186 } else { 187 // Select All Check and set to clickable state 188 checkBoxSelectAll.setSelected(true); 189 checkBoxSelectAll.setEnabled(false); 190 } 191 LinkedList<String> memoryFlushed = new LinkedList<>(); 192 for (JBCheckBox checkBox : selectedList) { 193 // When the checked quantity is 1, the last indicator item cannot be clicked 194 if (selectedList.size() == 1) { 195 checkBox.setEnabled(false); 196 } else { 197 checkBox.setEnabled(true); 198 } 199 memoryFlushed.add(checkBox.getText()); 200 } 201 configMap.remove(MEMORY_NAME); 202 configMap.put(MEMORY_NAME, memoryFlushed); 203 MonitorConfigManager.DATA_MAP.put(sessionId, configMap); 204 // Refresh chart manually 205 chartObserver.refreshManually(); 206 } 207 208 /** 209 * show memory items 210 * 211 * @param detailCfgBtn detailCfgBtn 212 * @param event event 213 */ showMemoryItems(JBLabel detailCfgBtn, MouseEvent event)214 void showMemoryItems(JBLabel detailCfgBtn, MouseEvent event) { 215 if (ProfilerLogManager.isInfoEnabled()) { 216 LOGGER.info("showMemoryItems"); 217 } 218 popupMenu.show(detailCfgBtn, event.getX(), event.getY() + POPUP_OFFSET); 219 } 220 } 221