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.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_COLLAPSEALLALL; import static com.insightfullogic.honest_profiler.ports.javafx.util.ResourceUtil.INFO_BUTTON_EXPANDALL; 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_TREEDIFF; import static com.insightfullogic.honest_profiler.ports.javafx.util.TreeUtil.expandFully; import static com.insightfullogic.honest_profiler.ports.javafx.util.TreeUtil.expandPartial; 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.DiffNode; import com.insightfullogic.honest_profiler.core.aggregation.result.diff.TreeDiff; import com.insightfullogic.honest_profiler.core.aggregation.result.straight.Tree; import com.insightfullogic.honest_profiler.ports.javafx.controller.filter.FilterDialogController; import com.insightfullogic.honest_profiler.ports.javafx.util.TreeUtil; import com.insightfullogic.honest_profiler.ports.javafx.view.cell.MethodNameTreeTableCell; import com.insightfullogic.honest_profiler.ports.javafx.view.tree.DiffNodeTreeItem; 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.TextField; import javafx.scene.control.TreeTableColumn; import javafx.scene.control.TreeTableView; /** * Controller for Views which displays the contents of a {@link TreeDiff} {@link Aggregation}. */ public class TreeDiffViewController extends AbstractProfileDiffViewController<Tree, DiffNode> { @FXML private Button filterButton; @FXML private Button expandAllButton; @FXML private Button collapseAllButton; @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 TreeTableView<DiffNode> treeDiffTable; @FXML private TreeTableColumn<DiffNode, String> methodColumn; @FXML private TreeTableColumn<DiffNode, Number> baseSelfCntPct; @FXML private TreeTableColumn<DiffNode, Number> newSelfCntPct; @FXML private TreeTableColumn<DiffNode, Number> selfCntPctDiff; @FXML private TreeTableColumn<DiffNode, Number> baseTotalCntPct; @FXML private TreeTableColumn<DiffNode, Number> newTotalCntPct; @FXML private TreeTableColumn<DiffNode, Number> totalCntPctDiff; @FXML private TreeTableColumn<DiffNode, Number> baseSelfCnt; @FXML private TreeTableColumn<DiffNode, Number> newSelfCnt; @FXML private TreeTableColumn<DiffNode, Number> selfCntDiff; @FXML private TreeTableColumn<DiffNode, Number> baseTotalCnt; @FXML private TreeTableColumn<DiffNode, Number> newTotalCnt; @FXML private TreeTableColumn<DiffNode, Number> totalCntDiff; @FXML private TreeTableColumn<DiffNode, Number> baseSelfTimePct; @FXML private TreeTableColumn<DiffNode, Number> newSelfTimePct; @FXML private TreeTableColumn<DiffNode, Number> selfTimePctDiff; @FXML private TreeTableColumn<DiffNode, Number> baseTotalTimePct; @FXML private TreeTableColumn<DiffNode, Number> newTotalTimePct; @FXML private TreeTableColumn<DiffNode, Number> totalTimePctDiff; @FXML private TreeTableColumn<DiffNode, Number> baseSelfTime; @FXML private TreeTableColumn<DiffNode, Number> newSelfTime; @FXML private TreeTableColumn<DiffNode, Number> selfTimeDiff; @FXML private TreeTableColumn<DiffNode, Number> baseTotalTime; @FXML private TreeTableColumn<DiffNode, Number> newTotalTime; @FXML private TreeTableColumn<DiffNode, Number> totalTimeDiff; @FXML private FilterDialogController<DiffNode> filterController; private TreeDiff diff; // FXML Implementation @Override @FXML protected void initialize() { diff = new TreeDiff(); 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(expandAllButton, INFO_BUTTON_EXPANDALL); info(collapseAllButton, INFO_BUTTON_COLLAPSEALLALL); info(quickFilterText, INFO_INPUT_QUICKFILTER); info(quickFilterButton, INFO_BUTTON_QUICKFILTER); info(treeDiffTable, INFO_TABLE_TREEDIFF); } @Override protected void initializeHandlers() { expandAllButton.setOnAction(event -> expandFully(treeDiffTable.getRoot())); collapseAllButton.setOnAction( event -> treeDiffTable.getRoot().getChildren().stream() .forEach(TreeUtil::collapseFully)); } // AbstractViewController Implementation @Override protected void refresh() { diff = new TreeDiff(); updateDiff(getBaseTarget(), getNewTarget()); } /** * Initializes the {@link TreeTableView} which displays the {@link TreeDiff} {@link Aggregation}. */ @Override protected void initializeTable() { methodColumn.setCellValueFactory( data -> new ReadOnlyStringWrapper( data.getValue() == null ? null : data.getValue().getValue().getKey())); methodColumn.setCellFactory(col -> new MethodNameTreeTableCell<>(appCtx())); 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 baseTree the Base {@link Tree} to be compared * @param newTree the New {@link Tree} to be compared */ private void updateDiff(Tree baseTree, Tree newTree) { if (baseTree != null && newTree != null) { diff.set(baseTree, newTree); treeDiffTable.setRoot(new DiffNodeTreeItem(diff.filter(getFilterSpecification()))); expandPartial(treeDiffTable.getRoot(), 2); treeDiffTable.sort(); } } }