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.icons.AllIcons; 19 import com.intellij.ui.components.JBPanel; 20 import com.intellij.ui.components.JBScrollPane; 21 import ohos.devtools.datasources.utils.device.entity.DeviceIPPortInfo; 22 import ohos.devtools.datasources.utils.process.entity.ProcessInfo; 23 import ohos.devtools.datasources.utils.process.service.ProcessManager; 24 import ohos.devtools.datasources.utils.session.service.SessionManager; 25 import ohos.devtools.views.common.LayoutConstants; 26 import ohos.devtools.views.layout.chartview.observer.ProfilerChartsViewPublisher; 27 import ohos.devtools.views.layout.chartview.observer.TimelineObserver; 28 29 import javax.swing.Icon; 30 import java.awt.BorderLayout; 31 import java.awt.event.ComponentAdapter; 32 import java.awt.event.ComponentEvent; 33 import java.lang.reflect.InvocationTargetException; 34 import java.util.HashMap; 35 import java.util.Map; 36 37 import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER; 38 import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED; 39 import static ohos.devtools.views.layout.chartview.utils.ChartViewConstants.TIMELINE_HEIGHT; 40 import static ohos.devtools.views.layout.chartview.utils.ChartViewConstants.TIMELINE_WIDTH; 41 42 /** 43 * Profiler Chart view main panel 44 * 45 * @since 2021/10/25 46 */ 47 public class ProfilerChartsView extends JBPanel { 48 /** 49 * Map of saving Session id and ProfilerChartsView 50 * 51 * @see "Key: Session id, value: ProfilerChartsView" 52 */ 53 public static Map<Long, ProfilerChartsView> sessionMap = new HashMap<>(); 54 55 /** 56 * Session id 57 */ 58 private final long sessionId; 59 60 /** 61 * Event publisher of charts display view 62 */ 63 private final ProfilerChartsViewPublisher publisher; 64 65 /** 66 * Panel to save timeline and monitor items 67 */ 68 private final JBPanel mainPanel; 69 70 /** 71 * Saves the parent panel of the current view 72 */ 73 private TaskScenePanelChart taskScenePanelChart; 74 75 /** 76 * Panel to save all monitor items 77 */ 78 private ItemsView itemsView; 79 80 /** 81 * User-defined horizontal scroll bar 82 */ 83 private ProfilerScrollbar horizontalBar; 84 85 /** 86 * User-defined timeline 87 */ 88 private ProfilerTimeline timeline; 89 90 /** 91 * User-defined loading panel 92 */ 93 private JBPanel loadingPanel; 94 95 private JBScrollPane itemsScroll; 96 97 /** 98 * Sign of pause 99 */ 100 private boolean pause = false; 101 102 /** 103 * Sign of stop 104 */ 105 private boolean stop = false; 106 107 /** 108 * Sign of add item 109 */ 110 private boolean addItemFlag = false; 111 112 /** 113 * Is chart loading (waiting for database to process data during initialization) 114 */ 115 private boolean loading = false; 116 117 /** 118 * Constructor 119 * 120 * @param sessionId Session id 121 * @param traceFile Is track file static import mode 122 * @param taskScenePanelChart Saves the parent panel of the current view 123 */ ProfilerChartsView(long sessionId, boolean traceFile, TaskScenePanelChart taskScenePanelChart)124 public ProfilerChartsView(long sessionId, boolean traceFile, TaskScenePanelChart taskScenePanelChart) { 125 super(true); 126 this.setOpaque(true); 127 this.setLayout(new BorderLayout()); 128 this.sessionId = sessionId; 129 this.taskScenePanelChart = taskScenePanelChart; 130 this.mainPanel = new JBPanel(new BorderLayout()); 131 this.add(mainPanel, BorderLayout.CENTER); 132 this.publisher = new ProfilerChartsViewPublisher(this, traceFile); 133 initTimeline(); 134 JBPanel timePanel = new JBPanel(new BorderLayout()); 135 timePanel.add(timeline, BorderLayout.NORTH); 136 if (!traceFile) { 137 // Add support for ability in specific processes 138 DeviceIPPortInfo deviceInfoBySessionId = 139 SessionManager.getInstance().getDeviceInfoBySessionId(sessionId); 140 ProcessInfo processInfo = 141 SessionManager.getInstance().getSessionInfo(sessionId).getProcessInfo(); 142 boolean isDebuggerProcess = 143 ProcessManager.getInstance().checkIsDebuggerProcess(deviceInfoBySessionId, processInfo); 144 } 145 this.mainPanel.add(timePanel, BorderLayout.NORTH); 146 initScrollPane(); 147 sessionMap.put(this.sessionId, this); 148 addResizedListener(); 149 } 150 151 /** 152 * Add listener for component size change 153 */ addResizedListener()154 private void addResizedListener() { 155 this.addComponentListener(new ComponentAdapter() { 156 @Override 157 public void componentResized(ComponentEvent event) { 158 // Adjust the size and position of the scroll bar when the component size changes 159 if (horizontalBar != null) { 160 horizontalBar.resizeAndReposition(); 161 } 162 } 163 }); 164 } 165 initTimeline()166 private void initTimeline() { 167 timeline = new ProfilerTimeline(TIMELINE_WIDTH, TIMELINE_HEIGHT); 168 // Save chart standard for timeline 169 timeline.setMaxDisplayTime(publisher.getStandard().getMaxDisplayMillis()); 170 timeline.setMinMarkInterval(publisher.getStandard().getMinMarkInterval()); 171 // Create the observer for timeline and register to the current view 172 TimelineObserver timelineObserver = new TimelineObserver(timeline); 173 publisher.attach(timelineObserver); 174 } 175 initScrollPane()176 private void initScrollPane() { 177 this.itemsView = new ItemsView(this); 178 itemsScroll = new JBScrollPane(itemsView, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_NEVER); 179 itemsScroll.getVerticalScrollBar().setUnitIncrement(LayoutConstants.SCROLL_UNIT_INCREMENT); 180 itemsScroll.addComponentListener(new ComponentAdapter() { 181 @Override 182 public void componentResized(ComponentEvent event) { 183 itemsView.updateShowHeight(event.getComponent().getHeight()); 184 } 185 }); 186 this.mainPanel.add(itemsScroll, BorderLayout.CENTER); 187 } 188 189 /** 190 * Initialize horizontal scroll bar 191 */ initScrollbar()192 public void initScrollbar() { 193 this.horizontalBar = new ProfilerScrollbar(this); 194 this.mainPanel.add(horizontalBar, BorderLayout.SOUTH); 195 this.publisher.setDisplayScrollbar(true); 196 } 197 198 /** 199 * Remove horizontal scroll bar 200 */ removeScrollbar()201 public void removeScrollbar() { 202 this.publisher.setDisplayScrollbar(false); 203 if (horizontalBar != null) { 204 this.mainPanel.remove(horizontalBar); 205 this.horizontalBar = null; 206 } 207 } 208 209 /** 210 * Show Loading panel 211 */ showLoading()212 public void showLoading() { 213 loadingPanel = new LoadingPanel(); 214 loading = true; 215 this.remove(mainPanel); 216 this.add(loadingPanel, BorderLayout.CENTER); 217 // Check the loading result: start the refresh after loading 218 publisher.checkLoadingResult(); 219 } 220 221 /** 222 * Hide Loading panel and show main panel 223 */ hideLoading()224 public void hideLoading() { 225 if (loadingPanel != null) { 226 this.remove(loadingPanel); 227 } 228 loading = false; 229 this.add(mainPanel, BorderLayout.CENTER); 230 } 231 232 /** 233 * Add a monitor item view 234 * 235 * @param item 指标项枚举类 236 * @throws InvocationTargetException InvocationTargetException 237 * @throws NoSuchMethodException NoSuchMethodException 238 * @throws InstantiationException InstantiationException 239 * @throws IllegalAccessException IllegalAccessException 240 */ addMonitorItemView(ProfilerMonitorItem item)241 public void addMonitorItemView(ProfilerMonitorItem item) 242 throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { 243 itemsView.addMonitorItemView(item); 244 } 245 246 /** 247 * Set pause status 248 * 249 * @param pause pause/resume 250 */ setPause(boolean pause)251 public void setPause(boolean pause) { 252 this.pause = pause; 253 Icon icon; 254 String text; 255 if (pause) { 256 icon = AllIcons.Process.ProgressResumeHover; 257 text = "Start"; 258 } else { 259 icon = AllIcons.Process.ProgressPauseHover; 260 text = "Suspend"; 261 if (itemsView != null) { 262 // Update the pop-up state of the table event after the left-click on all charts 263 itemsView.updateShowTableView(); 264 } 265 } 266 267 if (taskScenePanelChart != null && taskScenePanelChart.getjButtonStop() != null) { 268 taskScenePanelChart.getjButtonStop().setIcon(icon); 269 taskScenePanelChart.getjButtonStop().setToolTipText(text); 270 } 271 } 272 getPublisher()273 public ProfilerChartsViewPublisher getPublisher() { 274 return publisher; 275 } 276 getMainPanel()277 public JBPanel getMainPanel() { 278 return mainPanel; 279 } 280 getHorizontalBar()281 public ProfilerScrollbar getHorizontalBar() { 282 return horizontalBar; 283 } 284 getSessionId()285 public long getSessionId() { 286 return sessionId; 287 } 288 isPause()289 public boolean isPause() { 290 return pause; 291 } 292 isStop()293 public boolean isStop() { 294 return stop; 295 } 296 setStop(boolean stop)297 public void setStop(boolean stop) { 298 this.stop = stop; 299 } 300 isAddItemFlag()301 public boolean isAddItemFlag() { 302 return addItemFlag; 303 } 304 setAddItemFlag(boolean addItemFlag)305 public void setAddItemFlag(boolean addItemFlag) { 306 this.addItemFlag = addItemFlag; 307 } 308 getTimeline()309 public ProfilerTimeline getTimeline() { 310 return timeline; 311 } 312 getTaskScenePanelChart()313 public TaskScenePanelChart getTaskScenePanelChart() { 314 return taskScenePanelChart; 315 } 316 isLoading()317 public boolean isLoading() { 318 return loading; 319 } 320 getItemsView()321 public ItemsView getItemsView() { 322 return itemsView; 323 } 324 getItemsScroll()325 public JBScrollPane getItemsScroll() { 326 return itemsScroll; 327 } 328 } 329