< prev index next >

application/org.openjdk.jmc.flightrecorder.ui/src/main/java/org/openjdk/jmc/flightrecorder/ui/pages/ThreadsPage.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The contents of this file are subject to the terms of either the Universal Permissive License * v 1.0 as shown at http://oss.oracle.com/licenses/upl --- 1,8 ---- /* ! * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. ! * Copyright (c) 2019, Red Hat Inc. All rights reserved. * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The contents of this file are subject to the terms of either the Universal Permissive License * v 1.0 as shown at http://oss.oracle.com/licenses/upl
*** 42,53 **** --- 43,60 ---- import java.util.stream.Stream; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.Separator; import org.eclipse.jface.resource.ImageDescriptor; + import org.eclipse.jface.viewers.StructuredSelection; + import org.eclipse.jface.viewers.TableViewer; + import org.eclipse.jface.wizard.WizardPage; + import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; + import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; + import org.eclipse.swt.widgets.Item; import org.eclipse.ui.forms.widgets.FormToolkit; import org.openjdk.jmc.common.IMCThread; import org.openjdk.jmc.common.IState; import org.openjdk.jmc.common.IWritableState; import org.openjdk.jmc.common.item.Aggregators;
*** 67,92 **** --- 74,105 ---- import org.openjdk.jmc.flightrecorder.ui.IPageContainer; import org.openjdk.jmc.flightrecorder.ui.IPageDefinition; import org.openjdk.jmc.flightrecorder.ui.IPageUI; import org.openjdk.jmc.flightrecorder.ui.StreamModel; import org.openjdk.jmc.flightrecorder.ui.common.AbstractDataPage; + import org.openjdk.jmc.flightrecorder.ui.common.FilterComponent; import org.openjdk.jmc.flightrecorder.ui.common.FlavorSelector.FlavorSelectorState; import org.openjdk.jmc.flightrecorder.ui.common.ImageConstants; import org.openjdk.jmc.flightrecorder.ui.common.ItemHistogram; import org.openjdk.jmc.flightrecorder.ui.common.ItemHistogram.HistogramSelection; import org.openjdk.jmc.flightrecorder.ui.common.ItemHistogram.ItemHistogramBuilder; import org.openjdk.jmc.flightrecorder.ui.common.ItemRow; + import org.openjdk.jmc.flightrecorder.ui.common.DropdownLaneFilter; import org.openjdk.jmc.flightrecorder.ui.common.ThreadGraphLanes; import org.openjdk.jmc.flightrecorder.ui.messages.internal.Messages; + import org.openjdk.jmc.flightrecorder.ui.selection.SelectionStoreActionToolkit; import org.openjdk.jmc.ui.UIPlugin; import org.openjdk.jmc.ui.charts.IXDataRenderer; import org.openjdk.jmc.ui.charts.QuantitySpanRenderer; import org.openjdk.jmc.ui.charts.RendererToolkit; import org.openjdk.jmc.ui.column.ColumnManager.SelectionState; + import org.openjdk.jmc.ui.column.ColumnMenusFactory; import org.openjdk.jmc.ui.column.TableSettings; import org.openjdk.jmc.ui.handlers.ActionToolkit; import org.openjdk.jmc.ui.handlers.MCContextMenuManager; + import org.openjdk.jmc.ui.wizards.IPerformFinishable; + import org.openjdk.jmc.ui.wizards.OnePageWizardDialog; public class ThreadsPage extends AbstractDataPage { public static class ThreadsPageFactory implements IDataPageFactory {
*** 151,194 **** return null; }, Messages.JavaApplicationPage_COLUMN_THREAD_DURATION, Messages.JavaApplicationPage_COLUMN_THREAD_DURATION_DESC); } ! private class ThreadsPageUi extends ChartAndTableUI { private static final String THREADS_TABLE_FILTER = "threadsTableFilter"; //$NON-NLS-1$ private static final String HIDE_THREAD = "hideThread"; //$NON-NLS-1$ private static final String RESET_CHART = "resetChart"; //$NON-NLS-1$ private Boolean isChartMenuActionsInit; private Boolean isChartModified; private Boolean reloadThreads; private IAction hideThreadAction; private IAction resetChartAction; private List<IXDataRenderer> threadRows; private MCContextMenuManager mm; private ThreadGraphLanes lanes; ThreadsPageUi(Composite parent, FormToolkit toolkit, IPageContainer editor, IState state) { super(pageFilter, getDataSource(), parent, toolkit, editor, state, getName(), pageFilter, getIcon(), flavorSelectorState); mm = (MCContextMenuManager) chartCanvas.getContextMenu(); sash.setOrientation(SWT.HORIZONTAL); addActionsToContextMenu(mm); // FIXME: The lanes field is initialized by initializeChartConfiguration which is called by the super constructor. This is too indirect for SpotBugs to resolve and should be simplified. lanes.updateContextMenu(mm, false); - form.getToolBarManager() .add(ActionToolkit.action(() -> lanes.openEditLanesDialog(mm, false), Messages.ThreadsPage_EDIT_LANES, FlightRecorderUI.getDefault().getMCImageDescriptor(ImageConstants.ICON_LANES_EDIT))); form.getToolBarManager().update(true); chartLegend.getControl().dispose(); buildChart(); - table.getManager().setSelectionState(histogramSelectionState); - tableFilterComponent.loadState(state.getChild(THREADS_TABLE_FILTER)); chart.setVisibleRange(visibleRange.getStart(), visibleRange.getEnd()); onFilterChange(tableFilter); } /** * Hides a thread from the chart and rebuilds the chart */ private void hideThread(Object thread) { if (this.threadRows != null && this.threadRows.size() > 0 && thread instanceof IMCThread) { --- 164,217 ---- return null; }, Messages.JavaApplicationPage_COLUMN_THREAD_DURATION, Messages.JavaApplicationPage_COLUMN_THREAD_DURATION_DESC); } ! private class ThreadsPageUi extends ChartAndPopupTableUI { private static final String THREADS_TABLE_FILTER = "threadsTableFilter"; //$NON-NLS-1$ private static final String HIDE_THREAD = "hideThread"; //$NON-NLS-1$ private static final String RESET_CHART = "resetChart"; //$NON-NLS-1$ + private static final String TABLE = "table"; //$NON-NLS-1$ private Boolean isChartMenuActionsInit; private Boolean isChartModified; private Boolean reloadThreads; private IAction hideThreadAction; private IAction resetChartAction; private List<IXDataRenderer> threadRows; private MCContextMenuManager mm; private ThreadGraphLanes lanes; + private DropdownLaneFilter laneFilter; ThreadsPageUi(Composite parent, FormToolkit toolkit, IPageContainer editor, IState state) { super(pageFilter, getDataSource(), parent, toolkit, editor, state, getName(), pageFilter, getIcon(), flavorSelectorState); mm = (MCContextMenuManager) chartCanvas.getContextMenu(); sash.setOrientation(SWT.HORIZONTAL); addActionsToContextMenu(mm); // FIXME: The lanes field is initialized by initializeChartConfiguration which is called by the super constructor. This is too indirect for SpotBugs to resolve and should be simplified. lanes.updateContextMenu(mm, false); form.getToolBarManager() .add(ActionToolkit.action(() -> lanes.openEditLanesDialog(mm, false), Messages.ThreadsPage_EDIT_LANES, FlightRecorderUI.getDefault().getMCImageDescriptor(ImageConstants.ICON_LANES_EDIT))); + form.getToolBarManager() + .add(ActionToolkit.action(() -> openViewThreadDetailsDialog(state), Messages.ThreadsPage_VIEW_THREAD_DETAILS, + FlightRecorderUI.getDefault().getMCImageDescriptor(ImageConstants.ICON_TABLE))); form.getToolBarManager().update(true); chartLegend.getControl().dispose(); + setupFilterBar(); buildChart(); chart.setVisibleRange(visibleRange.getStart(), visibleRange.getEnd()); onFilterChange(tableFilter); } + private void setupFilterBar() { + laneFilter = new DropdownLaneFilter(filterBar, lanes, mm); + laneFilter.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); + filterBar.setChart(chart); + filterBar.setChartCanvas(chartCanvas); + } + /** * Hides a thread from the chart and rebuilds the chart */ private void hideThread(Object thread) { if (this.threadRows != null && this.threadRows.size() > 0 && thread instanceof IMCThread) {
*** 275,300 **** } @Override protected IXDataRenderer getChartRenderer(IItemCollection itemsInTable, HistogramSelection tableSelection) { List<IXDataRenderer> rows = new ArrayList<>(); ! IItemCollection selectedItems; HistogramSelection selection; if (tableSelection.getRowCount() == 0) { selectedItems = itemsInTable; ! selection = table.getAllRows(); } else { selectedItems = tableSelection.getItems(); selection = tableSelection; } boolean useDefaultSelection = rows.size() > 1; if (lanes.getLaneDefinitions().stream().anyMatch(a -> a.isEnabled()) && selection.getRowCount() > 0) { if (this.reloadThreads) { this.threadRows = selection .getSelectedRows((object, items) -> lanes.buildThreadRenderer(object, items)) .collect(Collectors.toList()); this.isChartModified = false; if (this.isChartMenuActionsInit) { setResetChartActionEnablement(false); setHideThreadActionEnablement(true); } --- 298,325 ---- } @Override protected IXDataRenderer getChartRenderer(IItemCollection itemsInTable, HistogramSelection tableSelection) { List<IXDataRenderer> rows = new ArrayList<>(); ! ItemHistogram histogram = getUndisposedTable(); IItemCollection selectedItems; HistogramSelection selection; if (tableSelection.getRowCount() == 0) { selectedItems = itemsInTable; ! selection = histogram.getAllRows(); } else { selectedItems = tableSelection.getItems(); selection = tableSelection; } boolean useDefaultSelection = rows.size() > 1; if (lanes.getLaneDefinitions().stream().anyMatch(a -> a.isEnabled()) && selection.getRowCount() > 0) { if (this.reloadThreads) { this.threadRows = selection .getSelectedRows((object, items) -> lanes.buildThreadRenderer(object, items)) .collect(Collectors.toList()); + chartCanvas.setNumItems(this.threadRows.size()); + textCanvas.setNumItems(this.threadRows.size()); this.isChartModified = false; if (this.isChartMenuActionsInit) { setResetChartActionEnablement(false); setHideThreadActionEnablement(true); }
*** 323,339 **** } @Override public void saveTo(IWritableState state) { super.saveTo(state); - tableFilterComponent.saveState(state.createChild(THREADS_TABLE_FILTER)); saveToLocal(); } private void saveToLocal() { flavorSelectorState = flavorSelector.getFlavorSelectorState(); ! histogramSelectionState = table.getManager().getSelectionState(); visibleRange = chart.getVisibleRange(); } @Override protected List<IAction> initializeChartConfiguration(IState state) { --- 348,363 ---- } @Override public void saveTo(IWritableState state) { super.saveTo(state); saveToLocal(); } private void saveToLocal() { flavorSelectorState = flavorSelector.getFlavorSelectorState(); ! histogramSelectionState = getUndisposedTable().getManager().getSelectionState(); visibleRange = chart.getVisibleRange(); } @Override protected List<IAction> initializeChartConfiguration(IState state) {
*** 341,352 **** --- 365,444 ---- this.isChartModified = false; this.reloadThreads = true; lanes = new ThreadGraphLanes(() -> getDataSource(), () -> buildChart()); return lanes.initializeChartConfiguration(Stream.of(state.getChildren(THREAD_LANE))); } + + private TablePopup tablePopup; + public void openViewThreadDetailsDialog(IState state) { + tablePopup = new TablePopup(state); + OnePageWizardDialog.openAndHideCancelButton(tablePopup, 500, 600); + } + + private class TablePopup extends WizardPage implements IPerformFinishable { + + private IState state; + + protected TablePopup(IState state) { + super("ThreadDetailsPage"); //$NON-NLS-1$ + this.state = state; + setTitle(Messages.ThreadsPage_TABLE_POPUP_TITLE); + setDescription(Messages.ThreadsPage_TABLE_POPUP_DESCRIPTION); + } + + @Override + public void createControl(Composite parent) { + table = buildHistogram(parent, state.getChild(TABLE)); + MCContextMenuManager mm = MCContextMenuManager.create(table.getManager().getViewer().getControl()); + ColumnMenusFactory.addDefaultMenus(table.getManager(), mm); + table.getManager().getViewer().addSelectionChangedListener(e -> buildChart()); + table.getManager().getViewer() + .addSelectionChangedListener(e -> pageContainer.showSelection(table.getSelection().getItems())); + SelectionStoreActionToolkit.addSelectionStoreActions(pageContainer.getSelectionStore(), table, + NLS.bind(Messages.ChartAndTableUI_HISTOGRAM_SELECTION, getName()), mm); + tableFilterComponent = FilterComponent.createFilterComponent(table.getManager().getViewer().getControl(), + table.getManager(), tableFilter, model.getItems().apply(pageFilter), + pageContainer.getSelectionStore()::getSelections, this::onFilterChangeHelper); + mm.add(tableFilterComponent.getShowFilterAction()); + mm.add(tableFilterComponent.getShowSearchAction()); + table.getManager().setSelectionState(histogramSelectionState); + tableFilterComponent.loadState(state.getChild(THREADS_TABLE_FILTER)); + onFilterChange(tableFilter); + + if (selectionInput != null) { + table.getManager().getViewer().setSelection(new StructuredSelection(selectionInput)); + } + + Item[] columnWidgets = ((TableViewer) table.getManager().getViewer()).getTable().getColumns(); + for (Item columWidget : columnWidgets) { + columWidget.addListener(SWT.Selection, e -> columnSortChanged()); + } + + setControl(parent); + } + + private void columnSortChanged() { + if (!table.getSelection().getItems().hasItems()) { + buildChart(); + } + } + + private void onFilterChangeHelper(IItemFilter filter) { + onFilterChange(filter); + } + + @Override + public boolean performFinish() { + IItemCollection lastSelection = table.getSelection().getItems(); + table.show(lastSelection); + selectionInput = (Object[]) table.getManager().getViewer().getInput(); + return true; + } + } } + private Object[] selectionInput; private FlavorSelectorState flavorSelectorState; private SelectionState histogramSelectionState; private IItemFilter tableFilter; private IRange<IQuantity> visibleRange;
< prev index next >