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.ui.components.JBPanel; 19 import ohos.devtools.views.layout.chartview.memory.MemoryItemView; 20 21 import javax.swing.SpringLayout; 22 import javax.swing.SpringLayout.Constraints; 23 import java.awt.Dimension; 24 import java.awt.event.ComponentAdapter; 25 import java.awt.event.ComponentEvent; 26 import java.lang.reflect.InvocationTargetException; 27 import java.util.ArrayList; 28 import java.util.List; 29 30 import static javax.swing.Spring.constant; 31 import static javax.swing.Spring.minus; 32 import static javax.swing.SpringLayout.EAST; 33 import static javax.swing.SpringLayout.SOUTH; 34 35 /** 36 * Save the custom layout panel of each indicator item View 37 * 38 * @since 2021/11/22 39 */ 40 public class ItemsView extends JBPanel { 41 private static final int ITEM_MIN_EXPAND_HEIGHT = 400; 42 private static final int ITEM_MIN_HEIGHT = 175; 43 44 private final SpringLayout spring = new SpringLayout(); 45 private final ProfilerChartsView bottomPanel; 46 private final List<MonitorItemView> items; 47 private int showHeight; 48 private int itemFoldHeight; 49 50 /** 51 * Constructor 52 * 53 * @param bottomPanel ProfilerChartsView 54 */ ItemsView(ProfilerChartsView bottomPanel)55 public ItemsView(ProfilerChartsView bottomPanel) { 56 this.setLayout(spring); 57 this.bottomPanel = bottomPanel; 58 this.items = new ArrayList<>(); 59 this.addComponentListener(new ComponentAdapter() { 60 @Override 61 public void componentResized(ComponentEvent event) { 62 adjustLayout(event.getComponent().getWidth()); 63 } 64 }); 65 } 66 updateShowHeight(int showHeight)67 void updateShowHeight(int showHeight) { 68 this.showHeight = showHeight; 69 adjustLayout(this.getWidth()); 70 } 71 72 /** 73 * update need ShowTable View 74 */ updateShowTableView()75 void updateShowTableView() { 76 for (MonitorItemView item : items) { 77 if (item instanceof MemoryItemView) { 78 MemoryItemView memoryItemView = (MemoryItemView) item; 79 JBPanel heapViewPanel = memoryItemView.getHeapViewPanel(); 80 if (heapViewPanel != null) { 81 memoryItemView.remove(heapViewPanel); 82 } 83 } 84 } 85 } 86 87 /** 88 * Add a monitor item view 89 * 90 * @param item Profiler monitor item enum 91 * @throws NoSuchMethodException NoSuchMethodException 92 * @throws IllegalAccessException NoSuchMethodException 93 * @throws InvocationTargetException InvocationTargetException 94 * @throws InstantiationException InstantiationException 95 */ addMonitorItemView(ProfilerMonitorItem item)96 void addMonitorItemView(ProfilerMonitorItem item) 97 throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { 98 MonitorItemView itemView = item.getClazz().getConstructor().newInstance(); 99 itemView.init(bottomPanel, this, item); 100 this.add(itemView); 101 items.add(itemView); 102 // Add item constraints 103 if (items.size() == 1) { 104 itemView.setPreferredSize(new Dimension(this.getWidth(), this.getHeight())); 105 spring.putConstraint(EAST, itemView, minus(constant(0)), EAST, this); 106 Constraints currentCons = spring.getConstraints(itemView); 107 currentCons.setX(constant(0)); 108 currentCons.setY(constant(0)); 109 } else { 110 Constraints previousCons = spring.getConstraints(items.get(items.size() - 1)); 111 Constraints currentCons = spring.getConstraints(itemView); 112 currentCons.setX(constant(0)); 113 // When there is more than one item, the current item is placed in the SOUTH of the previous one 114 currentCons.setY(previousCons.getConstraint(SOUTH)); 115 currentCons.setConstraint(EAST, previousCons.getConstraint(EAST)); 116 } 117 adjustLayout(this.getWidth()); 118 } 119 120 /** 121 * Adjust the layout of the current view,including constraints and size 122 * 123 * @param width width of this view 124 */ adjustLayout(int width)125 private void adjustLayout(int width) { 126 if (items.size() == 0) { 127 return; 128 } 129 130 if (items.size() == 1) { 131 items.get(0).setPreferredSize(new Dimension(width, this.getHeight())); 132 return; 133 } 134 135 // Calculate and save the single item height when all items are folded 136 int heightSize = items.size() * ITEM_MIN_HEIGHT; 137 boolean flag = heightSize > showHeight; 138 itemFoldHeight = flag ? ITEM_MIN_HEIGHT : showHeight / items.size(); 139 140 if (isItemExpend()) { 141 // If an item is expanded, there is no need to change the height 142 items.forEach(item -> { 143 int oldHeight = Double.valueOf(item.getPreferredSize().getHeight()).intValue(); 144 item.setPreferredSize(new Dimension(width, oldHeight)); 145 }); 146 } else { 147 items.forEach(item -> item.setPreferredSize(new Dimension(width, itemFoldHeight))); 148 } 149 150 // When there is only one item, there is no need to adjust the constraint 151 if (items.size() > 1) { 152 adjustConstraints(); 153 } 154 // Adjust the height of current view 155 adjustTotalSize(); 156 } 157 isItemExpend()158 private boolean isItemExpend() { 159 boolean expend = false; 160 for (MonitorItemView item : items) { 161 if (!item.isFold()) { 162 expend = true; 163 break; 164 } 165 } 166 return expend; 167 } 168 adjustConstraints()169 private void adjustConstraints() { 170 int size = items.size(); 171 for (int index = 1; index < size; index++) { 172 Constraints previousCons = spring.getConstraints(items.get(index - 1)); 173 Constraints currentCons = spring.getConstraints(items.get(index)); 174 currentCons.setX(constant(0)); 175 // the current item is placed in the SOUTH of the previous one 176 currentCons.setY(previousCons.getConstraint(SOUTH)); 177 currentCons.setConstraint(EAST, previousCons.getConstraint(EAST)); 178 } 179 } 180 adjustTotalSize()181 private void adjustTotalSize() { 182 int totalHeight = calcTotalHeight(); 183 this.setPreferredSize(new Dimension(this.getWidth(), totalHeight)); 184 } 185 calcTotalHeight()186 private int calcTotalHeight() { 187 int total = 0; 188 for (MonitorItemView item : items) { 189 total += Double.valueOf(item.getPreferredSize().getHeight()).intValue(); 190 } 191 return total; 192 } 193 194 /** 195 * Fold or expend the item 196 * 197 * @param fold ture: fold, false: expand 198 * @param item Monitor item view 199 */ itemFoldOrExpend(boolean fold, MonitorItemView item)200 public void itemFoldOrExpend(boolean fold, MonitorItemView item) { 201 if (items.size() == 1) { 202 return; 203 } 204 205 int newHeight; 206 if (fold) { 207 newHeight = itemFoldHeight; 208 } else { 209 newHeight = ITEM_MIN_EXPAND_HEIGHT; 210 } 211 item.setPreferredSize(new Dimension(this.getWidth(), newHeight)); 212 adjustLayout(this.getWidth()); 213 } 214 215 /** 216 * Click on chart of chart, expand item 217 * 218 * @param item MonitorItemView 219 */ itemChartClick(MonitorItemView item)220 public void itemChartClick(MonitorItemView item) { 221 if (items.size() > 1) { 222 item.setPreferredSize(new Dimension(this.getWidth(), showHeight)); 223 adjustLayout(this.getWidth()); 224 } 225 } 226 getItems()227 public List<MonitorItemView> getItems() { 228 return items; 229 } 230 } 231