/** * Copyright (c) 2014 Richard Warburton (richard.warburton@gmail.com) * <p> * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * associated documentation files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * <p> * The above copyright notice and this permission notice shall be included in all copies or * substantial portions of the Software. * <p> * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **/ package com.insightfullogic.honest_profiler.ports.javafx.controller; import static com.insightfullogic.honest_profiler.core.aggregation.result.ItemType.DIFFENTRY; import static com.insightfullogic.honest_profiler.ports.javafx.util.DialogUtil.showExportDialog; import static com.insightfullogic.honest_profiler.ports.javafx.util.FxUtil.refreshTable; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.COLUMN_SELF_CNT; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.COLUMN_SELF_CNT_DIFF; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.COLUMN_SELF_CNT_PCT; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.COLUMN_SELF_CNT_PCT_DIFF; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.COLUMN_SELF_TIME; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.COLUMN_SELF_TIME_DIFF; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.COLUMN_SELF_TIME_PCT; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.COLUMN_SELF_TIME_PCT_DIFF; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.COLUMN_TOTAL_CNT; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.COLUMN_TOTAL_CNT_DIFF; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.COLUMN_TOTAL_CNT_PCT; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.COLUMN_TOTAL_CNT_PCT_DIFF; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.COLUMN_TOTAL_TIME; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.COLUMN_TOTAL_TIME_DIFF; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.COLUMN_TOTAL_TIME_PCT; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.COLUMN_TOTAL_TIME_PCT_DIFF; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.INFO_BUTTON_EXPORT; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.INFO_BUTTON_FILTER; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.INFO_BUTTON_QUICKFILTER; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.INFO_INPUT_QUICKFILTER; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.INFO_TABLE_FLATDIFF; import static com.insightfullogic.honest_profiler.ports.javafx.util.report.ReportUtil.writeFlatProfileDiffCsv; import com.insightfullogic.honest_profiler.core.aggregation.grouping.FrameGrouping; import com.insightfullogic.honest_profiler.core.aggregation.grouping.ThreadGrouping; import com.insightfullogic.honest_profiler.core.aggregation.result.Aggregation; import com.insightfullogic.honest_profiler.core.aggregation.result.diff.DiffEntry; import com.insightfullogic.honest_profiler.core.aggregation.result.diff.FlatDiff; import com.insightfullogic.honest_profiler.core.aggregation.result.straight.Flat; import com.insightfullogic.honest_profiler.ports.javafx.controller.filter.FilterDialogController; import com.insightfullogic.honest_profiler.ports.javafx.util.report.ReportUtil; import com.insightfullogic.honest_profiler.ports.javafx.view.cell.MethodNameTableCell; import javafx.beans.property.ReadOnlyStringWrapper; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.control.ChoiceBox; import javafx.scene.control.Label; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.TextField; /** * Controller for Views which displays the contents of a {@link FlatDiff} {@link Aggregation}. */ public class FlatDiffViewController extends AbstractProfileDiffViewController<Flat, DiffEntry> { @FXML private Button filterButton; @FXML private Button exportButton; @FXML private TextField quickFilterText; @FXML private Button quickFilterButton; @FXML private Label threadGroupingLabel; @FXML private ChoiceBox<ThreadGrouping> threadGrouping; @FXML private Label frameGroupingLabel; @FXML private ChoiceBox<FrameGrouping> frameGrouping; @FXML private TableView<DiffEntry> flatDiffTable; @FXML private TableColumn<DiffEntry, String> method; @FXML private TableColumn<DiffEntry, Number> baseSelfCntPct; @FXML private TableColumn<DiffEntry, Number> newSelfCntPct; @FXML private TableColumn<DiffEntry, Number> selfCntPctDiff; @FXML private TableColumn<DiffEntry, Number> baseTotalCntPct; @FXML private TableColumn<DiffEntry, Number> newTotalCntPct; @FXML private TableColumn<DiffEntry, Number> totalCntPctDiff; @FXML private TableColumn<DiffEntry, Number> baseSelfCnt; @FXML private TableColumn<DiffEntry, Number> newSelfCnt; @FXML private TableColumn<DiffEntry, Number> selfCntDiff; @FXML private TableColumn<DiffEntry, Number> baseTotalCnt; @FXML private TableColumn<DiffEntry, Number> newTotalCnt; @FXML private TableColumn<DiffEntry, Number> totalCntDiff; @FXML private TableColumn<DiffEntry, Number> baseSelfTimePct; @FXML private TableColumn<DiffEntry, Number> newSelfTimePct; @FXML private TableColumn<DiffEntry, Number> selfTimePctDiff; @FXML private TableColumn<DiffEntry, Number> baseTotalTimePct; @FXML private TableColumn<DiffEntry, Number> newTotalTimePct; @FXML private TableColumn<DiffEntry, Number> totalTimePctDiff; @FXML private TableColumn<DiffEntry, Number> baseSelfTime; @FXML private TableColumn<DiffEntry, Number> newSelfTime; @FXML private TableColumn<DiffEntry, Number> selfTimeDiff; @FXML private TableColumn<DiffEntry, Number> baseTotalTime; @FXML private TableColumn<DiffEntry, Number> newTotalTime; @FXML private TableColumn<DiffEntry, Number> totalTimeDiff; @FXML private FilterDialogController<DiffEntry> filterController; private FlatDiff diff; // FXML Implementation @Override @FXML protected void initialize() { diff = new FlatDiff(); super.initialize(DIFFENTRY); super.initialize(filterController, filterButton, quickFilterButton, quickFilterText); super.initialize(threadGroupingLabel, threadGrouping, frameGroupingLabel, frameGrouping); } // AbstractController Implementation @Override protected void initializeInfoText() { info(filterButton, INFO_BUTTON_FILTER); info(exportButton, INFO_BUTTON_EXPORT); info(quickFilterText, INFO_INPUT_QUICKFILTER); info(quickFilterButton, INFO_BUTTON_QUICKFILTER); info(flatDiffTable, INFO_TABLE_FLATDIFF); } @Override protected void initializeHandlers() { exportButton.setOnAction( event -> showExportDialog( appCtx(), exportButton.getScene().getWindow(), "flat_diff_profile.csv", out -> writeFlatProfileDiffCsv(out, diff.getData(), ReportUtil.Mode.CSV) )); } // AbstractViewController Implementation @Override protected void refresh() { updateDiff(getBaseTarget(), getNewTarget()); } /** * Initializes the {@link TableView} which displays the {@link FlatDiff} {@link Aggregation}. */ @Override protected void initializeTable() { method.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().getKey())); method.setCellFactory(col -> new MethodNameTableCell<DiffEntry>()); cfgPctCol(baseSelfCntPct, "baseSelfCntPct", baseCtx(), getText(COLUMN_SELF_CNT_PCT)); cfgPctCol(newSelfCntPct, "newSelfCntPct", newCtx(), getText(COLUMN_SELF_CNT_PCT)); cfgPctDiffCol(selfCntPctDiff, "selfCntPctDiff", getText(COLUMN_SELF_CNT_PCT_DIFF)); cfgPctCol(baseTotalCntPct, "baseTotalCntPct", baseCtx(), getText(COLUMN_TOTAL_CNT_PCT)); cfgPctCol(newTotalCntPct, "newTotalCntPct", newCtx(), getText(COLUMN_TOTAL_CNT_PCT)); cfgPctDiffCol(totalCntPctDiff, "totalCntPctDiff", getText(COLUMN_TOTAL_CNT_PCT_DIFF)); cfgNrCol(baseSelfCnt, "baseSelfCnt", baseCtx(), getText(COLUMN_SELF_CNT)); cfgNrCol(newSelfCnt, "newSelfCnt", newCtx(), getText(COLUMN_SELF_CNT)); cfgNrDiffCol(selfCntDiff, "selfCntDiff", getText(COLUMN_SELF_CNT_DIFF)); cfgNrCol(baseTotalCnt, "baseTotalCnt", baseCtx(), getText(COLUMN_TOTAL_CNT)); cfgNrCol(newTotalCnt, "newTotalCnt", newCtx(), getText(COLUMN_TOTAL_CNT)); cfgNrDiffCol(totalCntDiff, "totalCntDiff", getText(COLUMN_TOTAL_CNT_DIFF)); cfgPctCol(baseSelfTimePct, "baseSelfTimePct", baseCtx(), getText(COLUMN_SELF_TIME_PCT)); cfgPctCol(newSelfTimePct, "newSelfTimePct", newCtx(), getText(COLUMN_SELF_TIME_PCT)); cfgPctDiffCol(selfTimePctDiff, "selfTimePctDiff", getText(COLUMN_SELF_TIME_PCT_DIFF)); cfgPctCol(baseTotalTimePct, "baseTotalTimePct", baseCtx(), getText(COLUMN_TOTAL_TIME_PCT)); cfgPctCol(newTotalTimePct, "newTotalTimePct", newCtx(), getText(COLUMN_TOTAL_TIME_PCT)); cfgPctDiffCol(totalTimePctDiff, "totalTimePctDiff", getText(COLUMN_TOTAL_TIME_PCT_DIFF)); cfgTimeCol(baseSelfTime, "baseSelfTime", baseCtx(), getText(COLUMN_SELF_TIME)); cfgTimeCol(newSelfTime, "newSelfTime", newCtx(), getText(COLUMN_SELF_TIME)); cfgTimeDiffCol(selfTimeDiff, "selfTimeDiff", getText(COLUMN_SELF_TIME_DIFF)); cfgTimeCol(baseTotalTime, "baseTotalTime", baseCtx(), getText(COLUMN_TOTAL_TIME)); cfgTimeCol(newTotalTime, "newTotalTime", newCtx(), getText(COLUMN_TOTAL_TIME)); cfgTimeDiffCol(totalTimeDiff, "totalTimeDiff", getText(COLUMN_TOTAL_TIME_DIFF)); } /** * Helper method for {@link #refresh()}. * <p> * * @param baseFlat the Base {@link Flat} to be compared * @param newFlat the New {@link Flat} to be compared */ private void updateDiff(Flat baseFlat, Flat newFlat) { if (baseFlat != null && newFlat != null) { diff.set(baseFlat, newFlat); flatDiffTable.getItems().clear(); flatDiffTable.getItems().addAll(diff.filter(getFilterSpecification()).getData()); refreshTable(flatDiffTable); flatDiffTable.sort(); } } }