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; 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.plugin.service.PlugManager; 23 24 import javax.swing.AbstractButton; 25 import javax.swing.JCheckBox; 26 import java.awt.Dimension; 27 import java.awt.FlowLayout; 28 import java.awt.event.ItemEvent; 29 import java.awt.event.ItemListener; 30 import java.awt.event.MouseEvent; 31 import java.util.ArrayList; 32 import java.util.HashMap; 33 import java.util.LinkedList; 34 import java.util.List; 35 import java.util.Map; 36 import java.util.stream.Collectors; 37 38 /** 39 * PerformanceIndexPopupMenu 40 * 41 * @since 2021/11/22 42 */ 43 public class PerformanceIndexPopupMenu { 44 private static final int OTHER_ITEM = 2; 45 private static final int HORIZONTAL_GAP = 15; 46 private static final int VERTICAL_GAP = 13; 47 private static final int ITEM_WIDTH = 140; 48 private static final int ITEM_HEIGHT = 20; 49 private static final int MEMORY_ITEM_PANEL_WIDTH = 160; 50 private static final int MARGIN_RIGHT = 160; 51 private static final int MEMORY_ITEM_HEIGHT = 35; 52 private static final int POPUP_OFFSET = 15; 53 private static final String ITEM = "item"; 54 55 private JBLabel titleLabel = new JBLabel("DataSource"); 56 private JBCheckBox checkBoxSelectAll = new JBCheckBox("Select all"); 57 private final LinkedList<String> ITEMS; 58 private final JBPopupMenu popupMenu; 59 private final ArrayList<JBCheckBox> allCheckBoxes; 60 private final List<MonitorItemView> cacheItemList; 61 private final Map<String, LinkedList<String>> map; 62 private final ProfilerChartsView profilerView; 63 private final List<ProfilerMonitorItem> profilerMonitorItemMap; 64 65 /** 66 * PerformanceIndexPopupMenu constructor 67 * 68 * @param profilerView profilerView 69 * @param sessionId sessionId 70 */ PerformanceIndexPopupMenu(ProfilerChartsView profilerView, long sessionId)71 public PerformanceIndexPopupMenu(ProfilerChartsView profilerView, long sessionId) { 72 this.profilerView = profilerView; 73 ITEMS = new LinkedList<>(); 74 popupMenu = new JBPopupMenu(); 75 allCheckBoxes = new ArrayList<>(); 76 cacheItemList = new ArrayList<>(); 77 map = new HashMap<>(); 78 profilerMonitorItemMap = PlugManager.getInstance().getProfilerMonitorItemList(sessionId); 79 addCheckBoxes(); 80 addCheckItemsToPanel(); 81 initItemPreferredSize(); 82 initDefaultCheck(); 83 initListener(); 84 } 85 initDefaultCheck()86 private void initDefaultCheck() { 87 for (JBCheckBox box : allCheckBoxes) { 88 box.setSelected(true); 89 } 90 } 91 addCheckBoxes()92 private void addCheckBoxes() { 93 for (ProfilerMonitorItem item : profilerMonitorItemMap) { 94 ITEMS.add(item.getName()); 95 } 96 map.put(ITEM, ITEMS); 97 for (String str : ITEMS) { 98 JBCheckBox checkBox = new JBCheckBox(str); 99 allCheckBoxes.add(checkBox); 100 } 101 } 102 addCheckItemsToPanel()103 private void addCheckItemsToPanel() { 104 JBPanel panel = new JBPanel(new FlowLayout(FlowLayout.LEADING, HORIZONTAL_GAP, VERTICAL_GAP)); 105 panel.add(titleLabel); 106 panel.add(checkBoxSelectAll); 107 for (JBCheckBox box : allCheckBoxes) { 108 panel.add(box); 109 } 110 panel.setPreferredSize( 111 new Dimension(MEMORY_ITEM_PANEL_WIDTH, (allCheckBoxes.size() + OTHER_ITEM) * MEMORY_ITEM_HEIGHT)); 112 popupMenu.add(panel); 113 } 114 initItemPreferredSize()115 private void initItemPreferredSize() { 116 titleLabel.setPreferredSize(new Dimension(ITEM_WIDTH, ITEM_HEIGHT)); 117 checkBoxSelectAll.setPreferredSize(new Dimension(ITEM_WIDTH, ITEM_HEIGHT)); 118 for (JBCheckBox box : allCheckBoxes) { 119 box.setPreferredSize(new Dimension(ITEM_WIDTH, ITEM_HEIGHT)); 120 } 121 } 122 initListener()123 private void initListener() { 124 checkBoxSelectAll.addItemListener(event -> { 125 if (checkBoxSelectAll.isSelected()) { 126 for (JBCheckBox box : allCheckBoxes) { 127 box.setSelected(true); 128 } 129 } else { 130 for (JBCheckBox box : allCheckBoxes) { 131 box.setSelected(false); 132 } 133 } 134 }); 135 ItemListener itemListener = new ItemListener() { 136 JCheckBox checkBox; 137 138 /** 139 * itemStateChanged 140 * 141 * @param event event 142 */ 143 public void itemStateChanged(ItemEvent event) { 144 Object sourceObject = event.getSource(); 145 if (sourceObject instanceof JCheckBox) { 146 checkBox = (JCheckBox) sourceObject; 147 String itemStr = checkBox.getText(); 148 filterItemList(); 149 if (checkBox.isSelected()) { 150 addItemView(itemStr); 151 } else { 152 reduceItemView(itemStr); 153 } 154 profilerView.getItemsView().revalidate(); 155 profilerView.getItemsView().repaint(); 156 } 157 } 158 }; 159 for (JBCheckBox box : allCheckBoxes) { 160 box.addItemListener(itemListener); 161 } 162 } 163 filterItemList()164 private void filterItemList() { 165 List<JBCheckBox> selectedList = 166 allCheckBoxes.stream().filter(AbstractButton::isSelected).collect(Collectors.toList()); 167 LinkedList<String> selectedItem = new LinkedList<>(); 168 for (JBCheckBox jc : selectedList) { 169 selectedItem.add(jc.getText()); 170 } 171 map.put(ITEM, selectedItem); 172 List<MonitorItemView> items = profilerView.getItemsView().getItems(); 173 if (cacheItemList.size() == 0) { 174 cacheItemList.addAll(items); 175 } 176 } 177 addItemView(String selectedStr)178 private void addItemView(String selectedStr) { 179 ItemsView itemsView = profilerView.getItemsView(); 180 List<MonitorItemView> items = profilerView.getItemsView().getItems(); 181 Class<? extends MonitorItemView> selectClass = null; 182 int selectIndex = 0; 183 // Get the class information according to the selected string 184 for (ProfilerMonitorItem item : profilerMonitorItemMap) { 185 if (selectedStr.equals(item.getName())) { 186 selectClass = item.getClazz(); 187 selectIndex = item.getIndex(); 188 } 189 } 190 if (items.size() == 1) { 191 items.get(0).setPreferredSize(new Dimension(items.get(0).getWidth(), 400)); 192 } 193 // Add the selected chart item to the chart again 194 for (MonitorItemView item : cacheItemList) { 195 if (selectClass.isInstance(item)) { 196 if (items.size() == 0) { 197 items.add(item); 198 itemsView.itemFoldOrExpend(false, item); 199 } 200 // Get the index of the item displayed in the interface through enumeration 201 addItemViewByIndex(itemsView, profilerMonitorItemMap, item, selectIndex); 202 } 203 } 204 if (items.size() == 1) { 205 items.get(0).setPreferredSize(new Dimension(items.get(0).getWidth(), itemsView.getHeight() - ITEM_HEIGHT)); 206 } 207 } 208 addItemViewByIndex(ItemsView itemsView, List<ProfilerMonitorItem> profilerMonitorItemMap, MonitorItemView item, int selectIndex)209 private void addItemViewByIndex(ItemsView itemsView, List<ProfilerMonitorItem> profilerMonitorItemMap, 210 MonitorItemView item, int selectIndex) { 211 List<MonitorItemView> items = profilerView.getItemsView().getItems(); 212 for (int index = 0; index < items.size(); index++) { 213 for (ProfilerMonitorItem monitorItem : profilerMonitorItemMap) { 214 if (monitorItem.getClazz().isInstance(items.get(index))) { 215 // The selected one is smaller than the first one and is added to the 0 position 216 if (selectIndex < monitorItem.getIndex() && index == 0) { 217 items.add(0, item); 218 itemsView.itemFoldOrExpend(false, item); 219 return; 220 } 221 // The selected one is larger than the last one, so add it directly 222 if (selectIndex > monitorItem.getIndex() && index == items.size() - 1) { 223 items.add(item); 224 itemsView.itemFoldOrExpend(false, item); 225 return; 226 } 227 // add Intermediate item 228 if (selectIndex < monitorItem.getIndex()) { 229 items.add(index, item); 230 itemsView.itemFoldOrExpend(false, item); 231 return; 232 } 233 } 234 } 235 } 236 } 237 reduceItemView(String notSelectStr)238 private void reduceItemView(String notSelectStr) { 239 List<MonitorItemView> items = profilerView.getItemsView().getItems(); 240 Class<? extends MonitorItemView> notSelectClass = null; 241 // Get the class information according to the unselected string 242 for (ProfilerMonitorItem item : profilerMonitorItemMap) { 243 if (notSelectStr.equals(item.getName())) { 244 notSelectClass = item.getClazz(); 245 } 246 } 247 // Delete the item view of chart according to the class information 248 for (MonitorItemView item : items) { 249 if (notSelectClass.isInstance(item)) { 250 hideItem(items, item); 251 break; 252 } 253 } 254 // resize 255 ItemsView itemsView = profilerView.getItemsView(); 256 for (MonitorItemView item : items) { 257 itemsView.itemFoldOrExpend(item.isFold(), item); 258 } 259 if (items.size() == 1) { 260 items.get(0).setPreferredSize(new Dimension(items.get(0).getWidth(), itemsView.getHeight() - ITEM_HEIGHT)); 261 } 262 } 263 hideItem(List<MonitorItemView> items, MonitorItemView item)264 private void hideItem(List<MonitorItemView> items, MonitorItemView item) { 265 item.setPreferredSize(new Dimension(item.getWidth(), 0)); 266 items.remove(item); 267 } 268 269 /** 270 * show ItemMenu 271 * 272 * @param event event 273 */ showItemMenu(MouseEvent event)274 public void showItemMenu(MouseEvent event) { 275 popupMenu.show(event.getComponent(), event.getX() - MARGIN_RIGHT, event.getY() + POPUP_OFFSET); 276 } 277 } 278