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.cpu; 17 18 import com.intellij.openapi.util.IconLoader; 19 import com.intellij.ui.JBColor; 20 import com.intellij.ui.components.JBLabel; 21 import com.intellij.ui.components.JBPanel; 22 import com.intellij.ui.components.JBTabbedPane; 23 import com.intellij.ui.components.JBTextField; 24 import net.miginfocom.swing.MigLayout; 25 import ohos.devtools.datasources.utils.device.entity.DeviceIPPortInfo; 26 import ohos.devtools.datasources.utils.device.entity.DeviceType; 27 import ohos.devtools.datasources.utils.monitorconfig.entity.AppTraceConfig; 28 import ohos.devtools.datasources.utils.monitorconfig.entity.ConfigInfo; 29 import ohos.devtools.datasources.utils.monitorconfig.entity.PerfConfig; 30 import ohos.devtools.views.common.ColorConstants; 31 import ohos.devtools.views.common.LayoutConstants; 32 import ohos.devtools.views.common.customcomp.CustomComboBox; 33 import ohos.devtools.views.common.customcomp.CustomJBComboBoxUI; 34 import ohos.devtools.views.layout.chartview.utils.DigitCheckDocument; 35 import ohos.devtools.views.layout.chartview.utils.MultiComboBox; 36 import ohos.devtools.views.layout.dialog.CustomDialog; 37 import org.apache.commons.lang.StringUtils; 38 import org.apache.logging.log4j.LogManager; 39 import org.apache.logging.log4j.Logger; 40 41 import javax.swing.BorderFactory; 42 import javax.swing.Icon; 43 import javax.swing.JButton; 44 import javax.swing.JSlider; 45 import javax.swing.JToggleButton; 46 import javax.swing.SwingWorker; 47 import javax.swing.event.DocumentEvent; 48 import javax.swing.event.DocumentListener; 49 import javax.swing.text.BadLocationException; 50 import java.awt.Dimension; 51 import java.awt.Font; 52 import java.awt.event.MouseAdapter; 53 import java.awt.event.MouseEvent; 54 import java.awt.event.WindowAdapter; 55 import java.awt.event.WindowEvent; 56 import java.util.ArrayList; 57 import java.util.Arrays; 58 import java.util.List; 59 import java.util.Locale; 60 61 /** 62 * CpuConfigDialog 63 * 64 * @since 2021/11/15 10:20 65 */ 66 public class CpuConfigDialog<T extends JBPanel<T>> { 67 private static final Logger LOGGER = LogManager.getLogger(CpuConfigDialog.class); 68 69 /** 70 * config Panel min width 71 */ 72 private static final int CONFIG_PANEL_MIN_WIDTH = 440; 73 74 /** 75 * config Panel min height 76 */ 77 private static final int CONFIG_PANEL_MIN_HEIGHT = 780; 78 79 /** 80 * config button width 81 */ 82 private static final int CONFIG_BUTTON_WIDTH = 80; 83 84 /** 85 * config button height 86 */ 87 private static final int CONFIG_BUTTON_HEIGHT = 30; 88 89 /** 90 * mMapPages Max value 91 */ 92 private static final int M_MAP_PAGES_MAX_VALUE = 10; 93 94 /** 95 * mMapPages Min value 96 */ 97 private static final int M_MAP_PAGES_MIN_VALUE = 1; 98 99 /** 100 * CPU percent max 101 */ 102 private static final int CPU_PERCENT_MAX = 100; 103 104 /** 105 * view Border distance 106 */ 107 private static final int VIEW_BORDER_DISTANCE = 8; 108 109 /** 110 * detailed bounds size 111 */ 112 private static final int BOUNDS_SIZE = 20; 113 114 /** 115 * detailed border size 116 */ 117 private static final int BORDER_SIZE = 2; 118 119 /** 120 * normal on 121 */ 122 private final Icon NORMAL_ON = IconLoader.getIcon("/images/normal_on.png", CpuConfigDialog.class); 123 124 /** 125 * normal off 126 */ 127 private final Icon NORMAL_OFF = IconLoader.getIcon("/images/normal_off.png", CpuConfigDialog.class); 128 129 /** 130 * label Font 131 */ 132 private final Font titleFont = new Font("PingFangSC-Regular;", Font.PLAIN, 14); 133 134 /** 135 * area Font 136 */ 137 private final Font messageFont = new Font("PingFangSC-Regular", Font.PLAIN, 12); 138 139 /** 140 * label font 141 */ 142 private final Font font = new Font(Font.DIALOG, Font.PLAIN, LayoutConstants.FONT_SIZE); 143 144 /** 145 * Cancel button 146 */ 147 private final JButton buttonCancel = new JButton("Cancel"); 148 149 /** 150 * Save button 151 */ 152 private final JButton buttonSave = new JButton("Save"); 153 154 /** 155 * Save button 156 */ 157 private final JButton restoreConfig = new JButton("Restore Config"); 158 159 /** 160 * deviceIPPortInfo 161 */ 162 private DeviceIPPortInfo deviceIPPortInfo; 163 164 /** 165 * perf Config Panel 166 */ 167 private JBPanel<T> perfConfigPanel; 168 169 /** 170 * appTrace Config Panel 171 */ 172 private JBPanel<T> appTraceConfigPanel; 173 174 /** 175 * tabbedPane 176 */ 177 private JBTabbedPane tabbedPane; 178 179 /** 180 * cpu List 181 */ 182 private final List<String> cpuList = new ArrayList<>(); 183 184 /** 185 * perf Config 186 */ 187 private PerfConfig<String> perfConfig; 188 189 /** 190 * AppTrace Config 191 */ 192 private AppTraceConfig appTraceConfig; 193 194 /** 195 * perfConfig 196 */ 197 private PerfConfig<String> restorePerfConfig; 198 199 /** 200 * cpu Num 201 */ 202 private int cpuNumber = 1; 203 204 /** 205 * isLeakOhos 206 */ 207 private boolean isLeakOhos; 208 209 /** 210 * eventList 211 */ 212 private List<String> eventList = new ArrayList<>(); 213 214 /** 215 * cpu Multi List 216 */ 217 private List<String> cpuMultiList = new ArrayList<>(); 218 219 /** 220 * event Multi List 221 */ 222 private List<String> eventMultiList = new ArrayList<>(); 223 224 /** 225 * configInfo 226 */ 227 private ConfigInfo configInfo; 228 229 /** 230 * configPanel 231 */ 232 private JBPanel<T> configPanel; 233 234 /** 235 * customDialog 236 */ 237 private CustomDialog customDialog; 238 239 /** 240 * configButton 241 */ 242 private JBLabel configButton; 243 244 /** 245 * multiCpuComboBox 246 */ 247 private MultiComboBox<String> multiCpuComboBox; 248 249 /** 250 * multiEventComboBox 251 */ 252 private MultiComboBox<String> multiEventComboBox; 253 254 /** 255 * CpuConfigDialog 256 * 257 * @param configButton configButton 258 * @param deviceIPPortInfo deviceIPPortInfo 259 */ CpuConfigDialog(JBLabel configButton, DeviceIPPortInfo deviceIPPortInfo)260 public CpuConfigDialog(JBLabel configButton, DeviceIPPortInfo deviceIPPortInfo) { 261 this.configButton = configButton; 262 this.deviceIPPortInfo = deviceIPPortInfo; 263 configButton.setName("open"); 264 configInfo = ConfigInfo.getInstance(); 265 initConfigPanel(); 266 } 267 initConfigPanel()268 private void initConfigPanel() { 269 new SwingWorker<>() { 270 @Override 271 protected Object doInBackground() { 272 initDefaultData(deviceIPPortInfo); 273 return new Object(); 274 } 275 276 @Override 277 protected void done() { 278 // JBTabbedPane 279 tabbedPane = new JBTabbedPane(); 280 // init ConfigTab 281 perfConfigPanel = new JBPanel<>(new MigLayout("insets 0", "[grow]", "[grow]")); 282 appTraceConfigPanel = new JBPanel<>(new MigLayout("insets 0", "[grow]", "[grow]")); 283 addTabPanel(perfConfigPanel, " PerfConfig"); 284 addPerfConfigTab(); 285 addTabPanel(appTraceConfigPanel, " APPTraceConfig"); 286 addAppTraceConfigTab(); 287 configPanel = new JBPanel<>(new MigLayout("insets 0 10 5 0", "[grow]", "[90%!,fill][10%!,fill]")); 288 configPanel.add(tabbedPane, "span, growx, growy"); 289 configPanel.setMinimumSize(new Dimension(CONFIG_PANEL_MIN_WIDTH, CONFIG_PANEL_MIN_HEIGHT)); 290 initConfigStyle(configPanel); 291 customDialog = new CustomDialog("Config", configPanel); 292 addConfigListener(); 293 customDialog.setResizable(false); 294 customDialog.show(); 295 } 296 }.execute(); 297 } 298 addTabPanel(JBPanel<T> configPanel, String name)299 private void addTabPanel(JBPanel<T> configPanel, String name) { 300 configPanel.setOpaque(true); 301 configPanel.setBorder(BorderFactory.createLineBorder(JBColor.green)); 302 // Config Tab 303 configPanel.setBorder(BorderFactory.createEmptyBorder(VIEW_BORDER_DISTANCE, 0, VIEW_BORDER_DISTANCE, 0)); 304 // Custom Config Tab 305 tabbedPane.addTab("", configPanel); 306 // PerfConfig Tab 307 JBLabel configLabel = new JBLabel(name); 308 configLabel.setBorder(BorderFactory.createEmptyBorder(BORDER_SIZE, BOUNDS_SIZE, BORDER_SIZE, 0)); 309 configLabel.setOpaque(false); 310 configLabel.setPreferredSize(new Dimension(LayoutConstants.JPA_LABEL_WIDTH, LayoutConstants.DEVICES_HEIGHT)); 311 configLabel.setFont(font); 312 configLabel 313 .setBounds(LayoutConstants.RECORD_BORDER_SPACE, BORDER_SIZE, LayoutConstants.RECORD_TABBED_BOUNDS_WIDTH, 314 BOUNDS_SIZE); 315 tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(configPanel), configLabel); 316 } 317 318 /** 319 * init Default Data 320 * 321 * @param deviceIPPortInfo deviceIPPortInfo 322 */ initDefaultData(DeviceIPPortInfo deviceIPPortInfo)323 private void initDefaultData(DeviceIPPortInfo deviceIPPortInfo) { 324 isLeakOhos = deviceIPPortInfo.getDeviceType() == DeviceType.LEAN_HOS_DEVICE; 325 String deviceID = deviceIPPortInfo.getDeviceID(); 326 perfConfig = configInfo.getPerfConfig(isLeakOhos); 327 appTraceConfig = configInfo.getAppTraceConfig(); 328 // set default cpu Number 329 eventList = perfConfig.getSoftHardWareEvents(isLeakOhos, deviceID); 330 cpuNumber = perfConfig.getCpuCount(isLeakOhos, deviceID); 331 restorePerfConfig = perfConfig; 332 } 333 334 /** 335 * init Config panel Style 336 * 337 * @param configPanel configPanel 338 */ initConfigStyle(JBPanel<T> configPanel)339 private void initConfigStyle(JBPanel<T> configPanel) { 340 buttonCancel.setFont(titleFont); 341 buttonSave.setFont(titleFont); 342 restoreConfig.setFont(titleFont); 343 buttonCancel.setPreferredSize(new Dimension(CONFIG_BUTTON_WIDTH, CONFIG_BUTTON_HEIGHT)); 344 buttonSave.setPreferredSize(new Dimension(CONFIG_BUTTON_WIDTH, CONFIG_BUTTON_HEIGHT)); 345 restoreConfig.setPreferredSize(new Dimension(CONFIG_BUTTON_WIDTH, CONFIG_BUTTON_HEIGHT)); 346 JBPanel<T> buttonPanel = new JBPanel<>(new MigLayout("insets 0", "[]210[][]")); 347 buttonPanel.add(restoreConfig); 348 buttonPanel.add(buttonCancel); 349 buttonPanel.add(buttonSave); 350 configPanel.add(buttonPanel); 351 } 352 353 /** 354 * add Config Panel Listener 355 */ addConfigListener()356 private void addConfigListener() { 357 buttonSave.addMouseListener(new MouseAdapter() { 358 @Override 359 public void mouseClicked(MouseEvent mouseEvent) { 360 eventMultiList = getInputContent(multiEventComboBox.getTextField().getText()); 361 perfConfig.setEventList(eventMultiList); 362 cpuMultiList = getInputContent(multiCpuComboBox.getTextField().getText()); 363 perfConfig.setCpuList(cpuMultiList); 364 configInfo.setPerfConfig(perfConfig); 365 configInfo.setAppTraceConfig(appTraceConfig); 366 configButton.setName("close"); 367 customDialog.close(1); 368 } 369 }); 370 buttonCancel.addMouseListener(new MouseAdapter() { 371 @Override 372 public void mouseClicked(MouseEvent event) { 373 super.mouseClicked(event); 374 perfConfig = restorePerfConfig; 375 configButton.setName("close"); 376 customDialog.close(1); 377 } 378 }); 379 restoreConfig.addMouseListener(new MouseAdapter() { 380 @Override 381 public void mouseClicked(MouseEvent event) { 382 super.mouseClicked(event); 383 configInfo.restorePerfDefault(isLeakOhos); 384 perfConfigPanel.removeAll(); 385 appTraceConfigPanel.removeAll(); 386 initDefaultData(deviceIPPortInfo); 387 appTraceConfig.setMemoryBufferSize(10); 388 addPerfConfigTab(); 389 addAppTraceConfigTab(); 390 perfConfigPanel.repaint(); 391 perfConfigPanel.validate(); 392 } 393 }); 394 395 customDialog.getWindow().addWindowListener(new WindowAdapter() { 396 @Override 397 public void windowClosed(WindowEvent event) { 398 super.windowClosed(event); 399 configButton.setName("close"); 400 } 401 }); 402 } 403 addAppTraceConfigTab()404 private void addAppTraceConfigTab() { 405 JBPanel<T> appTracePanel = 406 new JBPanel<>(new MigLayout("insets 0", "[80%!,fill]10[10%!,fill]", "10[5%!,fill][5%!,fill][80%!,fill]")); 407 // title label 408 JBLabel titleLabel = new JBLabel("In-memory buffer size"); 409 titleLabel.setOpaque(true); 410 titleLabel.setFont(titleFont); 411 appTracePanel.add(titleLabel, "span,wrap"); 412 // mMapPages Slider 413 JSlider unitSlider = new JSlider(0, 110); 414 // buffer size 415 int bufferSize = appTraceConfig.getMemoryBufferSize(); 416 unitSlider.setValue(bufferSize); 417 unitSlider.setMajorTickSpacing(10); 418 unitSlider.setMinorTickSpacing(1); 419 // ValuePanel 420 JBLabel valuePanel = new JBLabel("" + bufferSize + " MB", JBLabel.CENTER); 421 valuePanel.setFont(titleFont); 422 valuePanel.setVerticalTextPosition(JBLabel.CENTER); 423 valuePanel.setHorizontalTextPosition(JBLabel.CENTER); 424 valuePanel.setBackground(JBColor.background().brighter()); 425 valuePanel.setOpaque(true); 426 appTracePanel.add(unitSlider, "growx,growy"); 427 appTracePanel.add(valuePanel, "growx,growy,wrap"); 428 appTracePanel.add(new JBLabel(), "span,growx,growy"); 429 unitSlider.addChangeListener(event -> { 430 valuePanel.setText("" + unitSlider.getValue() + " MB"); 431 appTraceConfig.setMemoryBufferSize(unitSlider.getValue()); 432 }); 433 appTraceConfigPanel.add(appTracePanel, "span,growx,growy"); 434 } 435 436 /** 437 * add Perf Config Tab 438 */ addPerfConfigTab()439 private void addPerfConfigTab() { 440 addParameterComponent("CPU", "Record assign cpu num such as 0,1,2", ComponentType.MULTI_DROP_DOWN_BOX); 441 addParameterComponent("Event List", "Event type Default is cpu cycles", ComponentType.MULTI_DROP_DOWN_BOX); 442 addParameterComponent("CPU Percent", "Set the max percent of cpu time used for recording", 443 ComponentType.SLIDER_BAR); 444 addParameterComponent("Frequency", "Set event sampling frequency", ComponentType.INPUT_BOX); 445 addParameterComponent("Period", "Set event sampling period for trace point events", ComponentType.INPUT_BOX); 446 addParameterComponent("Is Off CPU", "Trace when threads are scheduled off cpu", ComponentType.TOGGLE_BUTTON); 447 addParameterComponent("No Inherit", "Don't trace child processes", ComponentType.TOGGLE_BUTTON); 448 addParameterComponent("Call Stack", "Setup and enable call stack recording", ComponentType.DROP_DOWN_BOX); 449 addParameterComponent("Branch", "Taken branch stack sampling", ComponentType.DROP_DOWN_BOX); 450 addParameterComponent("Mmap Pages", "Used to receiving record data from kernel", ComponentType.SLIDER_BAR); 451 addParameterComponent("Clock Type", 452 "Set the clock id to use for the various time fields in the perf_event_type records", 453 ComponentType.DROP_DOWN_BOX); 454 } 455 456 /** 457 * addParameterComponent 458 * 459 * @param name name 460 * @param Message Message 461 * @param componentType componentType 462 */ addParameterComponent(String name, String Message, ComponentType componentType)463 private void addParameterComponent(String name, String Message, ComponentType componentType) { 464 // title label 465 JBLabel titleLabel = new JBLabel(name); 466 titleLabel.setOpaque(true); 467 titleLabel.setFont(titleFont); 468 // message Label 469 JBLabel messageLabel = new JBLabel(Message); 470 messageLabel.setFont(messageFont); 471 messageLabel.setForeground(JBColor.foreground().darker()); 472 messageLabel.setOpaque(false); 473 switch (componentType) { 474 case INPUT_BOX: 475 perfConfigPanel.add(titleLabel, "split 2"); 476 perfConfigPanel.add(messageLabel, "span,flowx,wrap"); 477 buildInputBox(name); 478 break; 479 case SLIDER_BAR: 480 perfConfigPanel.add(titleLabel, "split 2"); 481 perfConfigPanel.add(messageLabel, "span,flowx,wrap"); 482 buildSliderBar(name); 483 break; 484 case DROP_DOWN_BOX: 485 perfConfigPanel.add(titleLabel, "split 2"); 486 perfConfigPanel.add(messageLabel, "span, flowx, wrap"); 487 buildDropDownBox(name); 488 break; 489 case TOGGLE_BUTTON: 490 perfConfigPanel.add(titleLabel, "split 2"); 491 perfConfigPanel.add(messageLabel, "flowx"); 492 buildToggleButton(name); 493 break; 494 case MULTI_DROP_DOWN_BOX: 495 perfConfigPanel.add(titleLabel, "split 2"); 496 perfConfigPanel.add(messageLabel, "span, flowx, wrap"); 497 buildMultiComboBox(name); 498 break; 499 default: 500 break; 501 } 502 } 503 504 /** 505 * build Multi DropDown Box 506 * 507 * @param name name 508 */ buildMultiComboBox(String name)509 private void buildMultiComboBox(String name) { 510 if (name.equals("CPU")) { 511 ArrayList<String> cpuArray = new ArrayList<>(); 512 cpuArray.add("Select All"); 513 for (int index = 0; index < cpuNumber; index++) { 514 cpuArray.add(index + ""); 515 } 516 multiCpuComboBox = new MultiComboBox<>(cpuArray); 517 multiCpuComboBox.setSelectValues(perfConfig.getCpuList()); 518 multiCpuComboBox.setName(name); 519 multiCpuComboBox.setFont(titleFont); 520 perfConfigPanel.add(multiCpuComboBox, "growx,growy,span,wrap"); 521 } 522 if (name.equals("Event List")) { 523 ArrayList<String> eventArray = new ArrayList<>(); 524 eventArray.add("Select All"); 525 eventArray.addAll(this.eventList); 526 multiEventComboBox = new MultiComboBox<>(eventArray); 527 multiEventComboBox.setSelectValues(perfConfig.getEventList()); 528 multiEventComboBox.setName(name); 529 multiEventComboBox.setFont(titleFont); 530 perfConfigPanel.add(multiEventComboBox, "growx,growy,span,wrap"); 531 } 532 } 533 getInputContent(String content)534 private List<String> getInputContent(String content) { 535 String contentText = content.replace("[", "").replace("]", "") 536 .replace(" ", "").strip(); 537 if (StringUtils.isBlank(content)) { 538 return new ArrayList<>(); 539 } 540 return Arrays.asList(contentText.split(",")); 541 } 542 543 /** 544 * build DropDown Box 545 * 546 * @param name name 547 */ buildDropDownBox(String name)548 private void buildDropDownBox(String name) { 549 List<String> dropList = new ArrayList<>(); 550 boolean isAddAll = false; 551 int selectIndex = 0; 552 switch (name) { 553 case "Call Stack": { 554 for (Enum anEnum : PerfConfig.CallStack.values()) { 555 dropList.add(anEnum.name().toLowerCase(Locale.ENGLISH)); 556 } 557 selectIndex = perfConfig.getCallStack(); 558 break; 559 } 560 case "Branch": { 561 for (Enum anEnum : PerfConfig.Branch.values()) { 562 dropList.add(anEnum.name().toLowerCase(Locale.ENGLISH)); 563 } 564 selectIndex = perfConfig.getBranch(); 565 break; 566 } 567 case "Clock Type": { 568 dropList = new ArrayList<>(); 569 for (Enum anEnum : PerfConfig.Clock.values()) { 570 dropList.add(anEnum.name().toLowerCase(Locale.ENGLISH)); 571 } 572 selectIndex = perfConfig.getClockId(); 573 break; 574 } 575 default: { 576 break; 577 } 578 } 579 // recordFeatures add Arrange by 580 CustomComboBox<String> arrangeBox = new CustomComboBox<>(); 581 arrangeBox.setFont(titleFont); 582 arrangeBox.setUI(new CustomJBComboBoxUI()); 583 arrangeBox.setBorder(BorderFactory.createLineBorder(ColorConstants.NATIVE_RECORD_BORDER, 1)); 584 if (isAddAll) { 585 arrangeBox.addItem("All"); 586 cpuList.add(String.valueOf(cpuList.size())); 587 } 588 for (String itemName : dropList) { 589 arrangeBox.addItem(itemName); 590 } 591 arrangeBox.setSelectedIndex(selectIndex); 592 perfConfigPanel.add(arrangeBox, "growx,growy,span,wrap"); 593 addArrangeBoxListener(name, arrangeBox); 594 } 595 596 /** 597 * build SliderBar 598 * 599 * @param name name 600 */ buildSliderBar(String name)601 private void buildSliderBar(String name) { 602 JSlider unitSlider; 603 JBLabel valuePanel; 604 if (name.contains("CPU")) { 605 int cpuPercent = perfConfig.getCpuPercent(); 606 // cpuPercent Slider 607 unitSlider = new JSlider(0, CPU_PERCENT_MAX); 608 unitSlider.setValue(cpuPercent); 609 unitSlider.setMajorTickSpacing(1); 610 // ValuePanel 611 valuePanel = new JBLabel("" + cpuPercent + " %", JBLabel.CENTER); 612 } else { 613 int mMapPages = perfConfig.getMmapPages(); 614 // mMapPages Slider 615 unitSlider = new JSlider(M_MAP_PAGES_MIN_VALUE, M_MAP_PAGES_MAX_VALUE); 616 unitSlider.setValue(logTwo(mMapPages)); 617 unitSlider.setMajorTickSpacing(12); 618 unitSlider.setMinorTickSpacing(2); 619 // ValuePanel 620 valuePanel = new JBLabel("" + mMapPages + " MB", JBLabel.CENTER); 621 } 622 valuePanel.setFont(titleFont); 623 valuePanel.setVerticalTextPosition(JBLabel.CENTER); 624 valuePanel.setHorizontalTextPosition(JBLabel.CENTER); 625 valuePanel.setOpaque(true); 626 perfConfigPanel.add(unitSlider, "growx,growy"); 627 perfConfigPanel.add(valuePanel, "growx,growy,wrap"); 628 valuePanel.setBackground(JBColor.background().brighter()); 629 addUnitSliderListener(unitSlider, valuePanel); 630 valuePanel.setFont(titleFont); 631 valuePanel.setVerticalTextPosition(JBLabel.CENTER); 632 valuePanel.setHorizontalTextPosition(JBLabel.CENTER); 633 } 634 635 /** 636 * build InputBox 637 * 638 * @param name name 639 */ buildInputBox(String name)640 private void buildInputBox(String name) { 641 JBTextField textField = new JBTextField(); 642 if (name.contains("Frequency")) { 643 textField.setName("Frequency"); 644 textField.setText(String.valueOf(perfConfig.getFrequency())); 645 } else { 646 textField.setName("Period"); 647 textField.setText(String.valueOf(perfConfig.getPeriod())); 648 } 649 textField.addMouseListener(new MouseAdapter() { 650 @Override 651 public void mouseExited(MouseEvent event) { 652 super.mouseExited(event); 653 if (textField.getName().contains("Frequency")) { 654 if (!textField.getText().equals("")) { 655 perfConfig.setFrequency(Integer.parseInt(textField.getText())); 656 } 657 } 658 if (textField.getName().contains("Period")) { 659 if (!textField.getText().equals("")) { 660 perfConfig.setPeriod(Integer.parseInt(textField.getText())); 661 } 662 } 663 } 664 }); 665 textField.getDocument().addDocumentListener(new DocumentListener() { 666 @Override 667 public void insertUpdate(DocumentEvent event) { 668 updateTextConfig(name, textField, event); 669 } 670 671 @Override 672 public void removeUpdate(DocumentEvent event) { 673 removeTextConfig(name, textField, event); 674 } 675 676 @Override 677 public void changedUpdate(DocumentEvent event) { 678 updateTextConfig(name, textField, event); 679 } 680 }); 681 perfConfigPanel.add(textField, "span,growx,growy,wrap"); 682 } 683 updateTextConfig(String name, JBTextField textField, DocumentEvent event)684 private void updateTextConfig(String name, JBTextField textField, DocumentEvent event) { 685 textField.setDocument(new DigitCheckDocument(5)); 686 int inputNumber = 0; 687 try { 688 String text = event.getDocument() 689 .getText(event.getDocument().getStartPosition().getOffset(), event.getDocument().getLength()); 690 inputNumber = Integer.parseInt(text); 691 } catch (BadLocationException | NumberFormatException exception) { 692 textField.setToolTipText("The input type is wrong, please select a number as input!"); 693 } 694 if (name.contains("Frequency")) { 695 perfConfig.setFrequency(inputNumber); 696 } else { 697 perfConfig.setPeriod(inputNumber); 698 } 699 } 700 removeTextConfig(String name, JBTextField textField, DocumentEvent event)701 private void removeTextConfig(String name, JBTextField textField, DocumentEvent event) { 702 try { 703 String text = event.getDocument() 704 .getText(event.getDocument().getStartPosition().getOffset(), event.getDocument().getLength()); 705 if (text == null) { 706 if (name.contains("Frequency")) { 707 perfConfig.setFrequency(0); 708 } else { 709 perfConfig.setPeriod(0); 710 } 711 } 712 } catch (BadLocationException exception) { 713 textField.setToolTipText("The input type is wrong, please select a number as input!"); 714 } 715 } 716 717 /** 718 * build ToggleButton 719 * 720 * @param name name 721 */ buildToggleButton(String name)722 private void buildToggleButton(String name) { 723 // JBRadioButton 724 JToggleButton toggleButton = name.contains("Is Off CPU") ? new JToggleButton("", perfConfig.isOffCpu()) 725 : new JToggleButton("", perfConfig.isInherit()); 726 toggleButton.setOpaque(true); 727 toggleButton.setBorderPainted(false); 728 toggleButton.setSelectedIcon(NORMAL_ON); 729 toggleButton.setIcon(NORMAL_OFF); 730 731 toggleButton.addMouseListener(new MouseAdapter() { 732 @Override 733 public void mouseReleased(MouseEvent event) { 734 super.mouseReleased(event); 735 if (name.contains("Is Off CPU")) { 736 perfConfig.setOffCpu(toggleButton.isSelected()); 737 } 738 if (name.contains("No Inherit")) { 739 perfConfig.setInherit(toggleButton.isSelected()); 740 } 741 } 742 }); 743 perfConfigPanel.add(toggleButton, "wrap"); 744 } 745 addArrangeBoxListener(String name, CustomComboBox<String> arrangeBox)746 private void addArrangeBoxListener(String name, CustomComboBox<String> arrangeBox) { 747 arrangeBox.addActionListener(event -> { 748 int selectedIndex = arrangeBox.getSelectedIndex(); 749 if (name.contains("Call Stack")) { 750 perfConfig.setCallStack(selectedIndex); 751 } 752 if (name.contains("Branch")) { 753 perfConfig.setBranch(selectedIndex); 754 } 755 if (name.contains("Clock Type")) { 756 perfConfig.setClockId(selectedIndex); 757 } 758 }); 759 } 760 addUnitSliderListener(JSlider unitSlider, JBLabel valuePanel)761 private void addUnitSliderListener(JSlider unitSlider, JBLabel valuePanel) { 762 unitSlider.addChangeListener(event -> { 763 if (unitSlider.getMajorTickSpacing() == 1) { 764 valuePanel.setText("" + unitSlider.getValue() + " %"); 765 perfConfig.setCpuPercent(unitSlider.getValue()); 766 } else { 767 double mMapValue = Math.pow(2, unitSlider.getValue()); 768 valuePanel.setText("" + (int) mMapValue + " MB"); 769 perfConfig.setMmapPages((int) mMapValue); 770 } 771 }); 772 } 773 774 /** 775 * getPerfConfig 776 * 777 * @return PerfConfig <String> 778 */ getPerfConfig()779 public PerfConfig<String> getPerfConfig() { 780 return perfConfig; 781 } 782 783 /** 784 * setPerfConfig 785 * 786 * @param perfConfig perfConfig 787 */ setPerfConfig(PerfConfig<String> perfConfig)788 public void setPerfConfig(PerfConfig<String> perfConfig) { 789 this.perfConfig = perfConfig; 790 } 791 792 /** 793 * ComponentType enum 794 */ 795 private enum ComponentType { 796 DROP_DOWN_BOX, SLIDER_BAR, INPUT_BOX, TOGGLE_BUTTON, MULTI_DROP_DOWN_BOX 797 } 798 logTwo(int value)799 private int logTwo(int value) { 800 if (value == 1) { 801 return 0; 802 } else { 803 return 1 + logTwo(value >> 1); 804 } 805 } 806 } 807