/**
* 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.ENTRY;
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_PCT;
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_PCT;
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_PCT;
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_PCT;
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_TREE;
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.straight.Node;
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.GraphicalShareTreeTableCell;
import com.insightfullogic.honest_profiler.ports.javafx.view.cell.MethodNameTreeTableCell;
import com.insightfullogic.honest_profiler.ports.javafx.view.tree.NodeTreeItem;
import javafx.beans.property.ReadOnlyObjectProperty;
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.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.TreeItemPropertyValueFactory;
/**
* Controller for Views which display the contents of a {@link Tree} {@link Aggregation}.
*/
public class TreeViewController extends AbstractProfileViewController<Tree, Node>
{
@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<Node> treeTable;
@FXML
private TreeTableColumn<Node, String> methodColumn;
@FXML
private TreeTableColumn<Node, Number> percentColumn;
@FXML
private TreeTableColumn<Node, Number> totalCntPct;
@FXML
private TreeTableColumn<Node, Number> selfCntPct;
@FXML
private TreeTableColumn<Node, Number> totalCnt;
@FXML
private TreeTableColumn<Node, Number> selfCnt;
@FXML
private TreeTableColumn<Node, Number> totalTimePct;
@FXML
private TreeTableColumn<Node, Number> selfTimePct;
@FXML
private TreeTableColumn<Node, Number> totalTime;
@FXML
private TreeTableColumn<Node, Number> selfTime;
@FXML
private FilterDialogController<Node> filterController;
// FXML Implementation
@Override
@FXML
protected void initialize()
{
super.initialize(ENTRY);
super.initialize(filterController, filterButton, quickFilterButton, quickFilterText);
super.initialize(threadGroupingLabel, threadGrouping, frameGroupingLabel, frameGrouping);
}
// Instance Accessors
/**
* Returns the {@link ReadOnlyObjectProperty} tracking which item is currently selected.
* <p>
*
* @return the {@link ReadOnlyObjectProperty} tracking which item is currently selected
*/
public ReadOnlyObjectProperty<TreeItem<Node>> selectedProperty()
{
return treeTable.getSelectionModel().selectedItemProperty();
}
// 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(treeTable, INFO_TABLE_TREE);
}
@Override
protected void initializeHandlers()
{
expandAllButton.setOnAction(event -> expandFully(treeTable.getRoot()));
collapseAllButton.setOnAction(
event -> treeTable.getRoot().getChildren().stream().forEach(TreeUtil::collapseFully));
}
// AbstractViewController Implementation
@Override
protected void refresh()
{
Tree target = getTarget();
if (target == null)
{
treeTable.setRoot(null);
}
else
{
treeTable.setRoot(new NodeTreeItem(getTarget().filter(getFilterSpecification())));
expandPartial(treeTable.getRoot(), 2);
}
treeTable.sort();
}
/**
* Initializes the {@link TreeTableView} which displays the {@link Tree} {@link Aggregation}.
*/
@Override
protected void initializeTable()
{
methodColumn.setCellFactory(column -> new MethodNameTreeTableCell<>(appCtx()));
methodColumn.setCellValueFactory(new TreeItemPropertyValueFactory<>("key"));
percentColumn.setCellValueFactory(new TreeItemPropertyValueFactory<>("totalCntPct"));
percentColumn.setCellFactory(param -> new GraphicalShareTreeTableCell());
cfgPctCol(totalCntPct, "totalCntPct", prfCtx(), COLUMN_TOTAL_CNT_PCT);
cfgPctCol(selfCntPct, "selfCntPct", prfCtx(), COLUMN_SELF_CNT_PCT);
cfgNrCol(totalCnt, "totalCnt", prfCtx(), COLUMN_TOTAL_CNT);
cfgNrCol(selfCnt, "selfCnt", prfCtx(), COLUMN_SELF_CNT);
cfgPctCol(totalTimePct, "totalTimePct", prfCtx(), COLUMN_TOTAL_TIME_PCT);
cfgPctCol(selfTimePct, "selfTimePct", prfCtx(), COLUMN_SELF_TIME_PCT);
cfgTimeCol(totalTime, "totalTime", prfCtx(), COLUMN_TOTAL_TIME);
cfgTimeCol(selfTime, "selfTime", prfCtx(), COLUMN_SELF_TIME);
}
}