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.trace.fragment; 17 18 import com.intellij.ui.JBColor; 19 import ohos.devtools.views.trace.component.AnalystPanel; 20 import ohos.devtools.views.trace.fragment.graph.AbstractGraph; 21 import ohos.devtools.views.trace.fragment.graph.CheckGraph; 22 import ohos.devtools.views.trace.fragment.graph.FavoriteGraph; 23 import ohos.devtools.views.trace.fragment.ruler.AbstractFragment; 24 import ohos.devtools.views.trace.util.Utils; 25 26 import javax.swing.JComponent; 27 import javax.swing.SwingUtilities; 28 import java.awt.AlphaComposite; 29 import java.awt.Graphics2D; 30 import java.awt.event.KeyEvent; 31 import java.awt.event.MouseEvent; 32 import java.sql.SQLException; 33 import java.sql.Statement; 34 import java.util.ArrayList; 35 import java.util.List; 36 import java.util.Objects; 37 import java.util.UUID; 38 39 import static java.util.Objects.nonNull; 40 41 /** 42 * Draw data rows 43 * 44 * @param <T> Plot data type 45 * @since 2021/04/22 12:25 46 */ 47 public abstract class AbstractDataFragment<T extends AbstractGraph> extends AbstractFragment { 48 /** 49 * uuid 50 */ 51 public String uuid = UUID.randomUUID().toString(); 52 53 /** 54 * is alive 55 */ 56 public boolean isAlive; 57 58 /** 59 * Parent node uuid 60 */ 61 public String parentUuid = UUID.randomUUID().toString(); 62 63 /** 64 * The default height can be modified. After hiding, the height of rect descRect dataRect is 0, 65 * no rendering, and the display restores the height according to defaultHeight 66 */ 67 public int defaultHeight = 40; 68 69 /** 70 * ndicates whether the data row is selected. 71 * null does not display the selected state. true/false displays the sufficient selection box 72 */ 73 public Boolean isSelected = false; 74 75 /** 76 * Whether to show 77 */ 78 public boolean visible = true; 79 80 /** 81 * Favorite button 82 */ 83 public FavoriteGraph favoriteGraph; 84 85 /** 86 * Select button 87 */ 88 public CheckGraph checkGraph; 89 90 /** 91 * Start event 92 */ 93 public long startNS; 94 95 /** 96 * End event 97 */ 98 public long endNS; 99 100 /** 101 * data list 102 */ 103 protected List<T> data; 104 105 /** 106 * Control query database thread 107 */ 108 private List<Statement> statement = new ArrayList<>(); 109 private IDataFragment dataFragmentListener; 110 private final boolean hasFavorite; 111 private final boolean hasCheck; 112 113 /** 114 * The construction method 115 * 116 * @param component component 117 * @param hasFavorite hasFavorite 118 * @param hasCheck hasCheck 119 */ AbstractDataFragment(JComponent component, boolean hasFavorite, boolean hasCheck)120 public AbstractDataFragment(JComponent component, boolean hasFavorite, boolean hasCheck) { 121 this.hasFavorite = hasFavorite; 122 this.hasCheck = hasCheck; 123 favoriteGraph = new FavoriteGraph(this, component, event -> { 124 if (nonNull(dataFragmentListener)) { 125 dataFragmentListener.collect(this); 126 } 127 }); 128 checkGraph = new CheckGraph(this, component); 129 } 130 131 /** 132 * Set to show or hide 133 * 134 * @param visible visible 135 */ setVisible(boolean visible)136 public void setVisible(boolean visible) { 137 this.visible = visible; 138 } 139 140 /** 141 * Time range interval change 142 * 143 * @param startNS Starting time 144 * @param endNS End Time 145 */ range(long startNS, long endNS)146 public void range(long startNS, long endNS) { 147 this.startNS = startNS; 148 this.endNS = endNS; 149 } 150 151 /** 152 * Data click event 153 * 154 * @param event event 155 */ mouseClicked(MouseEvent event)156 public void mouseClicked(MouseEvent event) { 157 if (favoriteGraph.isFavorite()) { 158 MouseEvent me = SwingUtilities.convertMouseEvent(getRoot(), event, getRoot().getParent()); 159 if (favoriteGraph.edgeInspect(me)) { 160 favoriteGraph.onClick(me); 161 } 162 if (checkGraph.edgeInspect(me)) { 163 checkGraph.onClick(me); 164 } 165 } else { 166 if (favoriteGraph.edgeInspect(event)) { 167 favoriteGraph.onClick(event); 168 } 169 if (checkGraph.edgeInspect(event)) { 170 checkGraph.onClick(event); 171 } 172 } 173 } 174 175 /** 176 * Mouse click event 177 * 178 * @param event event 179 */ mousePressed(MouseEvent event)180 public abstract void mousePressed(MouseEvent event); 181 182 /** 183 * Mouse exited event 184 * 185 * @param event event 186 */ mouseExited(MouseEvent event)187 public abstract void mouseExited(MouseEvent event); 188 189 /** 190 * Mouse entered event 191 * 192 * @param event event 193 */ mouseEntered(MouseEvent event)194 public abstract void mouseEntered(MouseEvent event); 195 196 /** 197 * Mouse move event 198 * 199 * @param event event 200 */ mouseMoved(MouseEvent event)201 public void mouseMoved(MouseEvent event) { 202 favoriteGraph.display(edgeInspectRect(getDescRect(), event)); 203 if (hasFavorite && !visible) { 204 if (favoriteGraph.edgeInspect(event)) { 205 if (!favoriteGraph.flagFocus) { 206 favoriteGraph.flagFocus = true; 207 favoriteGraph.onFocus(event); 208 } 209 } else { 210 if (favoriteGraph.flagFocus) { 211 favoriteGraph.flagFocus = false; 212 favoriteGraph.onBlur(event); 213 } 214 } 215 } 216 } 217 218 /** 219 * Mouse release event 220 * 221 * @param event event 222 */ mouseReleased(MouseEvent event)223 public abstract void mouseReleased(MouseEvent event); 224 225 /** 226 * Drawing method 227 * 228 * @param graphics graphics 229 */ 230 @Override draw(Graphics2D graphics)231 public void draw(Graphics2D graphics) { 232 if (endNS == 0) { 233 endNS = AnalystPanel.getDURATION(); 234 } 235 getRect().width = getRoot().getWidth(); 236 getDescRect().width = 200; 237 getDataRect().width = getRoot().getWidth() - 200; 238 graphics.setColor(JBColor.background().darker()); 239 graphics.fillRect(201, getRect().y + 1, getDataRect().width, getRect().height - 1); 240 graphics.setColor(getRoot().getForeground()); 241 graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f)); 242 graphics.drawLine(Utils.getX(getRect()), Utils.getY(getRect()) + getRect().height, getRoot().getWidth(), 243 Utils.getY(getRect()) + getRect().height); 244 graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f)); 245 if (hasCheck) { 246 checkGraph.setChecked(isSelected); 247 checkGraph.draw(graphics); 248 } 249 if (hasFavorite) { 250 if (hasCheck) { 251 favoriteGraph.setRightGraph(isSelected != null ? checkGraph : null); 252 } 253 favoriteGraph.draw(graphics); 254 } 255 } 256 257 /** 258 * Calculate the x coordinate based on time 259 * 260 * @param ns time 261 * @return int x coordinate 262 */ getX(long ns)263 public int getX(long ns) { 264 if (endNS == 0) { 265 endNS = AnalystPanel.getDURATION(); 266 } 267 int xSize = (int) ((ns - startNS) * getDataRect().width / (endNS - startNS)); 268 if (xSize < 0) { 269 xSize = 0; 270 } 271 if (xSize > getDataRect().width) { 272 xSize = getDataRect().width; 273 } 274 return xSize; 275 } 276 277 /** 278 * Calculate the x coordinate based on time 279 * 280 * @param ns time 281 * @return double Returns the x coordinate 282 */ getXDouble(long ns)283 public double getXDouble(long ns) { 284 if (endNS == 0) { 285 endNS = AnalystPanel.getDURATION(); 286 } 287 double xSize = (ns - startNS) * getDataRect().width / (endNS - startNS); 288 if (xSize < 0) { 289 xSize = 0; 290 } 291 if (xSize > getDataRect().width) { 292 xSize = getDataRect().width; 293 } 294 return xSize; 295 } 296 297 /** 298 * Clear focus 299 * 300 * @param event Mouse event 301 */ clearFocus(MouseEvent event)302 public void clearFocus(MouseEvent event) { 303 if (edgeInspect(event)) { 304 CpuDataFragment.focusCpuData = null; 305 } 306 } 307 308 /** 309 * The control component is drawn once 310 */ drawFrame()311 public void drawFrame() { 312 if (data != null) { 313 data.clear(); 314 data = null; 315 repaint(); 316 } 317 } 318 319 /** 320 * Clear selection element 321 */ clearSelected()322 public void clearSelected() { 323 if (nonNull(CpuDataFragment.currentSelectedCpuData)) { 324 CpuDataFragment.currentSelectedCpuData.select(false); 325 CpuDataFragment.currentSelectedCpuData.repaint(); 326 } 327 if (nonNull(ThreadDataFragment.currentSelectedThreadData)) { 328 ThreadDataFragment.currentSelectedThreadData.select(false); 329 ThreadDataFragment.currentSelectedThreadData.repaint(); 330 } 331 if (nonNull(FunctionDataFragment.currentSelectedFunctionData)) { 332 FunctionDataFragment.currentSelectedFunctionData.setSelected(false); 333 FunctionDataFragment.currentSelectedFunctionData.repaint(); 334 } 335 } 336 337 /** 338 * Set rect object 339 * 340 * @param xSize x coordinate 341 * @param ySize y coordinate 342 * @param width width 343 * @param height height 344 */ setRect(int xSize, int ySize, int width, int height)345 public void setRect(int xSize, int ySize, int width, int height) { 346 getRect().setLocation(xSize, ySize); 347 getRect().width = width; 348 getRect().height = height; 349 } 350 351 /** 352 * Gets the value of dataFragmentListener . 353 * 354 * @return the value of ohos.devtools.views.trace.fragment.AbstractDataFragment.IDataFragment 355 */ getDataFragmentListener()356 public IDataFragment getDataFragmentListener() { 357 return dataFragmentListener; 358 } 359 360 /** 361 * Sets the dataFragmentListener . 362 * <p>You can use getDataFragmentListener() to get the value of dataFragmentListener</p> 363 * 364 * @param listener listener 365 */ setDataFragmentListener(IDataFragment listener)366 public void setDataFragmentListener(IDataFragment listener) { 367 this.dataFragmentListener = listener; 368 } 369 370 /** 371 * recycle the data 372 */ recycle()373 public void recycle() { 374 if (data != null) { 375 data.clear(); 376 } 377 } 378 379 /** 380 * get the real mouse event 381 * 382 * @param evt MouseEvent 383 * @return MouseEvent 384 */ getRealMouseEvent(MouseEvent evt)385 public MouseEvent getRealMouseEvent(MouseEvent evt) { 386 MouseEvent event; 387 if (favoriteGraph.isFavorite()) { 388 event = SwingUtilities.convertMouseEvent(getRoot(), evt, getRoot().getParent()); 389 } else { 390 event = evt; 391 } 392 return event; 393 } 394 395 /** 396 * key released 397 * 398 * @param event event 399 */ keyReleased(KeyEvent event)400 public abstract void keyReleased(KeyEvent event); 401 402 /** 403 * get the click mouse event is empty 404 * 405 * @param event MouseEvent 406 * @return return the click point is in function or thread 407 */ isEmptyClick(MouseEvent event)408 public boolean isEmptyClick(MouseEvent event) { 409 if (Objects.nonNull(data)) { 410 return data.stream().allMatch(it -> !it.rect.contains(event.getPoint())); 411 } 412 return true; 413 } 414 415 /** 416 * addStatement 417 * 418 * @param st st 419 */ addStatement(Statement st)420 public void addStatement(Statement st) { 421 statement.add(st); 422 } 423 424 /** 425 * cancel 426 */ cancel()427 public void cancel() { 428 if (!statement.isEmpty()) { 429 for (Statement st : statement) { 430 if (st != null) { 431 try { 432 st.cancel(); 433 } catch (SQLException exception) { 434 exception.printStackTrace(); 435 } 436 } 437 } 438 statement.clear(); 439 } 440 } 441 442 ; 443 444 /** 445 * IDataFragment 446 * 447 * @since 2021/04/22 12:25 448 */ 449 public interface IDataFragment { 450 /** 451 * collect Callback 452 * 453 * @param fgr data 454 */ collect(AbstractDataFragment fgr)455 void collect(AbstractDataFragment fgr); 456 457 /** 458 * check Callback 459 * 460 * @param fgr data 461 */ check(AbstractDataFragment fgr)462 void check(AbstractDataFragment fgr); 463 } 464 } 465