From 47290d4853cfcfb7b62af754ada61e5106b0a6a4 Mon Sep 17 00:00:00 2001 From: ghidragon <106987263+ghidragon@users.noreply.github.com> Date: Fri, 5 May 2023 16:21:33 -0400 Subject: [PATCH] GP-3399 fixed stack trace when reusing graph displays. --- .../visualization/DefaultGraphDisplay.java | 416 +++++++++--------- .../DefaultGraphDisplayProvider.java | 22 +- 2 files changed, 219 insertions(+), 219 deletions(-) diff --git a/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphDisplay.java b/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphDisplay.java index 33df25fe9b..7f010550df 100644 --- a/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphDisplay.java +++ b/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphDisplay.java @@ -207,7 +207,7 @@ public class DefaultGraphDisplay implements GraphDisplay { viewer.setInitialDimensionFunction( InitialDimensionFunction.builder(viewer.getRenderContext().getVertexBoundsFunction()) - .build()); + .build()); createToolbarActions(); createPopupActions(); connectSelectionStateListeners(); @@ -255,19 +255,19 @@ public class DefaultGraphDisplay implements GraphDisplay { viewer.getRenderContext().getMultiLayerTransformer().getTransformer(VIEW); MagnifyShapeTransformer shapeTransformer = MagnifyShapeTransformer.builder(lens) - // this lens' delegate is the viewer's VIEW layer, abandoned above - .delegate(transformer) - .build(); + // this lens' delegate is the viewer's VIEW layer, abandoned above + .delegate(transformer) + .build(); LensGraphMouse lensGraphMouse = DefaultLensGraphMouse.builder() - .magnificationFloor(1.f) - .magnificationCeiling(60.f) - .magnificationDelta(.2f) - .build(); - return MagnifyImageLensSupport.builder(viewer) - .lensTransformer(shapeTransformer) - .lensGraphMouse(lensGraphMouse) + .magnificationFloor(1.f) + .magnificationCeiling(60.f) + .magnificationDelta(.2f) .build(); + return MagnifyImageLensSupport.builder(viewer) + .lensTransformer(shapeTransformer) + .lensGraphMouse(lensGraphMouse) + .build(); } private void buildHighlighers() { @@ -278,20 +278,20 @@ public class DefaultGraphDisplay implements GraphDisplay { // for highlighting of multiple selected vertices this.multiSelectedVertexPaintable = MultiSelectedVertexPaintable.builder(viewer) - .selectionStrokeMin(15.f) - .selectionPaint(getSelectedVertexColor()) - .useBounds(true) - .useOval(true) - .highlightScale(1.15) - .fillHighlight(false) - .build(); + .selectionStrokeMin(15.f) + .selectionPaint(getSelectedVertexColor()) + .useBounds(true) + .useOval(true) + .highlightScale(1.15) + .fillHighlight(false) + .build(); // manages highlight painting of a single selected vertex this.singleSelectedVertexPaintable = SingleSelectedVertexPaintable.builder(viewer) - .selectionStrokeMin(4.f) - .selectionPaint(getSelectedVertexColor()) - .selectedVertexFunction(vs -> this.focusedVertex) - .build(); + .selectionStrokeMin(4.f) + .selectionPaint(getSelectedVertexColor()) + .selectedVertexFunction(vs -> this.focusedVertex) + .build(); // draws the selection highlights viewer.addPreRenderPaintable(multiSelectedVertexPaintable); @@ -302,9 +302,9 @@ public class DefaultGraphDisplay implements GraphDisplay { viewer.removePreRenderPaintable(selectedEdgePaintable); this.selectedEdgePaintable = SelectedEdgePaintable.builder(viewer) - .selectionPaintFunction(e -> getSelectedEdgeColor()) - .selectionStrokeMultiplier(2) - .build(); + .selectionPaintFunction(e -> getSelectedEdgeColor()) + .selectionStrokeMultiplier(2) + .build(); viewer.addPreRenderPaintable(selectedEdgePaintable); @@ -317,209 +317,209 @@ public class DefaultGraphDisplay implements GraphDisplay { // create a toggle for 'scroll to selected vertex' new ToggleActionBuilder("Scroll To Selection", ACTION_OWNER) - .toolBarIcon(Icons.NAVIGATE_ON_INCOMING_EVENT_ICON) - .description("Ensure that the 'focused' vertex is visible") - .selected(true) - .onAction(context -> ensureVertexIsVisible = - ((AbstractButton) context.getSourceObject()).isSelected()) - .buildAndInstallLocal(componentProvider); + .toolBarIcon(Icons.NAVIGATE_ON_INCOMING_EVENT_ICON) + .description("Ensure that the 'focused' vertex is visible") + .selected(true) + .onAction(context -> ensureVertexIsVisible = + ((AbstractButton) context.getSourceObject()).isSelected()) + .buildAndInstallLocal(componentProvider); this.ensureVertexIsVisible = true; // since we initialized action to selected // create a toggle for enabling 'free-form' selection: selection is inside of a traced // shape instead of a rectangle new ToggleActionBuilder("Free-Form Selection", ACTION_OWNER) - .toolBarIcon(DefaultDisplayGraphIcons.LASSO_ICON) - .description("Trace Free-Form Shape to select multiple vertices (CTRL-click-drag)") - .selected(false) - .onAction(context -> freeFormSelection = - ((AbstractButton) context.getSourceObject()).isSelected()) - .buildAndInstallLocal(componentProvider); + .toolBarIcon(DefaultDisplayGraphIcons.LASSO_ICON) + .description("Trace Free-Form Shape to select multiple vertices (CTRL-click-drag)") + .selected(false) + .onAction(context -> freeFormSelection = + ((AbstractButton) context.getSourceObject()).isSelected()) + .buildAndInstallLocal(componentProvider); // create an icon button to display the satellite view new ToggleActionBuilder("SatelliteView", ACTION_OWNER).description("Show Satellite View") - .toolBarIcon(DefaultDisplayGraphIcons.SATELLITE_VIEW_ICON) - .onAction(this::toggleSatellite) - .selected(graphDisplayProvider.getDefaultSatelliteState()) - .buildAndInstallLocal(componentProvider); + .toolBarIcon(DefaultDisplayGraphIcons.SATELLITE_VIEW_ICON) + .onAction(this::toggleSatellite) + .selected(graphDisplayProvider.getDefaultSatelliteState()) + .buildAndInstallLocal(componentProvider); // create an icon button to reset the view transformations to identity (scaled to layout) new ActionBuilder("Reset View", ACTION_OWNER).description("Fit Graph to Window") - .toolBarIcon(DefaultDisplayGraphIcons.FIT_TO_WINDOW) - .onAction(context -> centerAndScale()) - .buildAndInstallLocal(componentProvider); + .toolBarIcon(DefaultDisplayGraphIcons.FIT_TO_WINDOW) + .onAction(context -> centerAndScale()) + .buildAndInstallLocal(componentProvider); // create a button to show the view magnify lens LensSupport magnifyViewSupport = createMagnifier(); ToggleDockingAction lensToggle = new ToggleActionBuilder("View Magnifier", ACTION_OWNER) - .description("Show View Magnifier") - .toolBarIcon(DefaultDisplayGraphIcons.VIEW_MAGNIFIER_ICON) - .onAction(context -> magnifyViewSupport - .activate(((AbstractButton) context.getSourceObject()).isSelected())) - .build(); + .description("Show View Magnifier") + .toolBarIcon(DefaultDisplayGraphIcons.VIEW_MAGNIFIER_ICON) + .onAction(context -> magnifyViewSupport + .activate(((AbstractButton) context.getSourceObject()).isSelected())) + .build(); magnifyViewSupport.addItemListener( itemEvent -> lensToggle.setSelected(itemEvent.getStateChange() == ItemEvent.SELECTED)); componentProvider.addLocalAction(lensToggle); // create an action button to show a dialog with generated filters new ActionBuilder("Show Filters", ACTION_OWNER).description("Show Graph Filters") - .toolBarIcon(DefaultDisplayGraphIcons.FILTER_ICON) - .onAction(context -> showFilterDialog()) - .buildAndInstallLocal(componentProvider); + .toolBarIcon(DefaultDisplayGraphIcons.FILTER_ICON) + .onAction(context -> showFilterDialog()) + .buildAndInstallLocal(componentProvider); // create a menu with graph layout algorithm selections List> layoutActionStates = getLayoutActionStates(); layoutAction = new MultiStateActionBuilder("Arrangement", ACTION_OWNER) - .description("Arrangement: " + layoutActionStates.get(0).getName()) - .toolBarIcon(DefaultDisplayGraphIcons.LAYOUT_ALGORITHM_ICON) - .useCheckboxForIcons(true) - .onActionStateChanged((s, t) -> layoutChanged(s.getName())) - .addStates(layoutActionStates) - .buildAndInstallLocal(componentProvider); + .description("Arrangement: " + layoutActionStates.get(0).getName()) + .toolBarIcon(DefaultDisplayGraphIcons.LAYOUT_ALGORITHM_ICON) + .useCheckboxForIcons(true) + .onActionStateChanged((s, t) -> layoutChanged(s.getName())) + .addStates(layoutActionStates) + .buildAndInstallLocal(componentProvider); } private void createPopupActions() { new ActionBuilder("Select Vertex", ACTION_OWNER).popupMenuPath("Select Vertex") - .popupMenuGroup("selection", "1") - .withContext(VertexGraphActionContext.class) - .enabledWhen(c -> !isSelected(c.getClickedVertex())) - .onAction(c -> viewer.getSelectedVertexState().select(c.getClickedVertex())) - .buildAndInstallLocal(componentProvider); + .popupMenuGroup("selection", "1") + .withContext(VertexGraphActionContext.class) + .enabledWhen(c -> !isSelected(c.getClickedVertex())) + .onAction(c -> viewer.getSelectedVertexState().select(c.getClickedVertex())) + .buildAndInstallLocal(componentProvider); new ActionBuilder("Deselect Vertex", ACTION_OWNER).popupMenuPath("Deselect Vertex") - .popupMenuGroup("selection", "2") - .withContext(VertexGraphActionContext.class) - .enabledWhen(c -> isSelected(c.getClickedVertex())) - .onAction(c -> viewer.getSelectedVertexState().deselect(c.getClickedVertex())) - .buildAndInstallLocal(componentProvider); + .popupMenuGroup("selection", "2") + .withContext(VertexGraphActionContext.class) + .enabledWhen(c -> isSelected(c.getClickedVertex())) + .onAction(c -> viewer.getSelectedVertexState().deselect(c.getClickedVertex())) + .buildAndInstallLocal(componentProvider); new ActionBuilder("Select Edge", ACTION_OWNER).popupMenuPath("Select Edge") - .popupMenuGroup("selection", "1") - .withContext(EdgeGraphActionContext.class) - .enabledWhen(c -> !isSelected(c.getClickedEdge())) - .onAction(c -> selectEdge(c.getClickedEdge())) - .buildAndInstallLocal(componentProvider); + .popupMenuGroup("selection", "1") + .withContext(EdgeGraphActionContext.class) + .enabledWhen(c -> !isSelected(c.getClickedEdge())) + .onAction(c -> selectEdge(c.getClickedEdge())) + .buildAndInstallLocal(componentProvider); new ActionBuilder("Deselect Edge", ACTION_OWNER).popupMenuPath("Deselect Edge") - .popupMenuGroup("selection", "2") - .withContext(EdgeGraphActionContext.class) - .enabledWhen(c -> isSelected(c.getClickedEdge())) - .onAction(c -> deselectEdge(c.getClickedEdge())) - .buildAndInstallLocal(componentProvider); + .popupMenuGroup("selection", "2") + .withContext(EdgeGraphActionContext.class) + .enabledWhen(c -> isSelected(c.getClickedEdge())) + .onAction(c -> deselectEdge(c.getClickedEdge())) + .buildAndInstallLocal(componentProvider); new ActionBuilder("Edge Source", ACTION_OWNER).popupMenuPath("Go To Edge Source") - .popupMenuGroup("Go To") - .withContext(EdgeGraphActionContext.class) - .onAction(c -> { - selectEdge(c.getClickedEdge()); - setFocusedVertex(graph.getEdgeSource(c.getClickedEdge())); - }) - .buildAndInstallLocal(componentProvider); + .popupMenuGroup("Go To") + .withContext(EdgeGraphActionContext.class) + .onAction(c -> { + selectEdge(c.getClickedEdge()); + setFocusedVertex(graph.getEdgeSource(c.getClickedEdge())); + }) + .buildAndInstallLocal(componentProvider); new ActionBuilder("Edge Target", ACTION_OWNER).popupMenuPath("Go To Edge Target") - .popupMenuGroup("Go To") - .withContext(EdgeGraphActionContext.class) - .onAction(c -> { - selectEdge(c.getClickedEdge()); - setFocusedVertex(graph.getEdgeTarget(c.getClickedEdge())); - }) - .buildAndInstallLocal(componentProvider); + .popupMenuGroup("Go To") + .withContext(EdgeGraphActionContext.class) + .onAction(c -> { + selectEdge(c.getClickedEdge()); + setFocusedVertex(graph.getEdgeTarget(c.getClickedEdge())); + }) + .buildAndInstallLocal(componentProvider); hideSelectedAction = new ToggleActionBuilder("Hide Selected", ACTION_OWNER).popupMenuPath("Hide Selected") - .popupMenuGroup("z", "1") - .description("Toggles whether or not to show selected vertices and edges") - .onAction(c -> manageVertexDisplay()) - .buildAndInstallLocal(componentProvider); - - hideUnselectedAction = new ToggleActionBuilder("Hide Unselected", ACTION_OWNER) - .popupMenuPath("Hide Unselected") - .popupMenuGroup("z", "2") + .popupMenuGroup("z", "1") .description("Toggles whether or not to show selected vertices and edges") .onAction(c -> manageVertexDisplay()) .buildAndInstallLocal(componentProvider); + hideUnselectedAction = new ToggleActionBuilder("Hide Unselected", ACTION_OWNER) + .popupMenuPath("Hide Unselected") + .popupMenuGroup("z", "2") + .description("Toggles whether or not to show selected vertices and edges") + .onAction(c -> manageVertexDisplay()) + .buildAndInstallLocal(componentProvider); + new ActionBuilder("Invert Selection", ACTION_OWNER).popupMenuPath("Invert Selection") - .popupMenuGroup("z", "3") - .description("Inverts the current selection") - .onAction(c -> invertSelection()) - .buildAndInstallLocal(componentProvider); + .popupMenuGroup("z", "3") + .description("Inverts the current selection") + .onAction(c -> invertSelection()) + .buildAndInstallLocal(componentProvider); new ActionBuilder("Grow Selection To Targets", ACTION_OWNER) - .popupMenuPath("Grow Selection To Targets") - .popupMenuGroup("z", "4") - .description("Extends the current selection by including the target vertex " + - "of all edges whose source is selected") - .keyBinding("ctrl O") - .enabledWhen(c -> !isAllSelected(getTargetVerticesFromSelected())) - .onAction(c -> growSelection(getTargetVerticesFromSelected())) - .buildAndInstallLocal(componentProvider); + .popupMenuPath("Grow Selection To Targets") + .popupMenuGroup("z", "4") + .description("Extends the current selection by including the target vertex " + + "of all edges whose source is selected") + .keyBinding("ctrl O") + .enabledWhen(c -> !isAllSelected(getTargetVerticesFromSelected())) + .onAction(c -> growSelection(getTargetVerticesFromSelected())) + .buildAndInstallLocal(componentProvider); new ActionBuilder("Grow Selection From Sources", ACTION_OWNER) - .popupMenuPath("Grow Selection From Sources") - .popupMenuGroup("z", "4") - .description("Extends the current selection by including the target vertex " + - "of all edges whose source is selected") - .keyBinding("ctrl I") - .enabledWhen(c -> !isAllSelected(getSourceVerticesFromSelected())) - .onAction(c -> growSelection(getSourceVerticesFromSelected())) - .buildAndInstallLocal(componentProvider); + .popupMenuPath("Grow Selection From Sources") + .popupMenuGroup("z", "4") + .description("Extends the current selection by including the target vertex " + + "of all edges whose source is selected") + .keyBinding("ctrl I") + .enabledWhen(c -> !isAllSelected(getSourceVerticesFromSelected())) + .onAction(c -> growSelection(getSourceVerticesFromSelected())) + .buildAndInstallLocal(componentProvider); new ActionBuilder("Grow Selection To Entire Component", ACTION_OWNER) - .popupMenuPath("Grow Selection To Entire Component") - .popupMenuGroup("z", "4") - .description( - "Extends the current selection by including the target/source vertices " + - "of all edges whose source/target is selected") - .keyBinding("ctrl C") - .enabledWhen(c -> !isAllSelected(getSourceVerticesFromSelected()) || - !isAllSelected(getTargetVerticesFromSelected())) - .onAction(c -> growSelection(getAllComponentVerticesFromSelected())) - .buildAndInstallLocal(componentProvider); + .popupMenuPath("Grow Selection To Entire Component") + .popupMenuGroup("z", "4") + .description( + "Extends the current selection by including the target/source vertices " + + "of all edges whose source/target is selected") + .keyBinding("ctrl C") + .enabledWhen(c -> !isAllSelected(getSourceVerticesFromSelected()) || + !isAllSelected(getTargetVerticesFromSelected())) + .onAction(c -> growSelection(getAllComponentVerticesFromSelected())) + .buildAndInstallLocal(componentProvider); new ActionBuilder("Clear Selection", ACTION_OWNER).popupMenuPath("Clear Selection") - .popupMenuGroup("z", "5") - .keyBinding("escape") - .enabledWhen(c -> hasSelection()) - .onAction(c -> clearSelection(true)) - .buildAndInstallLocal(componentProvider); + .popupMenuGroup("z", "5") + .keyBinding("escape") + .enabledWhen(c -> hasSelection()) + .onAction(c -> clearSelection(true)) + .buildAndInstallLocal(componentProvider); new ActionBuilder("Create Subgraph", ACTION_OWNER) - .popupMenuPath("Display Selected as New Graph") - .popupMenuGroup("zz", "5") - .description("Creates a subgraph from the selected nodes") - .enabledWhen(c -> !viewer.getSelectedVertices().isEmpty()) - .onAction(c -> createAndDisplaySubGraph()) - .buildAndInstallLocal(componentProvider); + .popupMenuPath("Display Selected as New Graph") + .popupMenuGroup("zz", "5") + .description("Creates a subgraph from the selected nodes") + .enabledWhen(c -> !viewer.getSelectedVertices().isEmpty()) + .onAction(c -> createAndDisplaySubGraph()) + .buildAndInstallLocal(componentProvider); new ActionBuilder("Collapse Selected", ACTION_OWNER) - .popupMenuPath("Collapse Selected Vertices") - .popupMenuGroup("zz", "6") - .description("Collapses the selected vertices into one collapsed vertex") - .onAction(c -> groupSelectedVertices()) - .buildAndInstallLocal(componentProvider); + .popupMenuPath("Collapse Selected Vertices") + .popupMenuGroup("zz", "6") + .description("Collapses the selected vertices into one collapsed vertex") + .onAction(c -> groupSelectedVertices()) + .buildAndInstallLocal(componentProvider); new ActionBuilder("Expand Selected", ACTION_OWNER).popupMenuPath("Expand Selected Vertices") - .popupMenuGroup("zz", "6") - .description("Expands all selected collapsed vertices into their previous form") - .onAction(c -> ungroupSelectedVertices()) - .buildAndInstallLocal(componentProvider); + .popupMenuGroup("zz", "6") + .description("Expands all selected collapsed vertices into their previous form") + .onAction(c -> ungroupSelectedVertices()) + .buildAndInstallLocal(componentProvider); new ActionBuilder("Graph Type Display Options", ACTION_OWNER) - .popupMenuPath("Graph Type Options ...") - .popupMenuGroup("zzz") - .menuPath("Graph Type Options ...") - .description("Brings up option editor for configuring vertex and edge types.") - .onAction(c -> editGraphDisplayOptions()) - .buildAndInstallLocal(componentProvider); + .popupMenuPath("Graph Type Options ...") + .popupMenuGroup("zzz") + .menuPath("Graph Type Options ...") + .description("Brings up option editor for configuring vertex and edge types.") + .onAction(c -> editGraphDisplayOptions()) + .buildAndInstallLocal(componentProvider); togglePopupsAction = new ToggleActionBuilder("Display Popup Windows", ACTION_OWNER) - .popupMenuPath("Display Popup Windows") - .popupMenuGroup("zz", "1") - .description("Toggles whether or not to show popup windows, such as tool tips") - .selected(true) - .onAction(c -> popupRegulator.setPopupsVisible(togglePopupsAction.isSelected())) - .buildAndInstallLocal(componentProvider); + .popupMenuPath("Display Popup Windows") + .popupMenuGroup("zz", "1") + .description("Toggles whether or not to show popup windows, such as tool tips") + .selected(true) + .onAction(c -> popupRegulator.setPopupsVisible(togglePopupsAction.isSelected())) + .buildAndInstallLocal(componentProvider); popupRegulator.setPopupsVisible(togglePopupsAction.isSelected()); } @@ -656,8 +656,8 @@ public class DefaultGraphDisplay implements GraphDisplay { MutableSelectedState selectedVertexState = viewer.getSelectedVertexState(); return getSourceVerticesFromSelected().stream() - .filter(v -> !selectedVertexState.isSelected(v)) - .collect(Collectors.toSet()); + .filter(v -> !selectedVertexState.isSelected(v)) + .collect(Collectors.toSet()); } private Set getTargetVerticesFromSelected() { @@ -674,8 +674,8 @@ public class DefaultGraphDisplay implements GraphDisplay { MutableSelectedState selectedVertexState = viewer.getSelectedVertexState(); return getTargetVerticesFromSelected().stream() - .filter(v -> !selectedVertexState.isSelected(v)) - .collect(Collectors.toSet()); + .filter(v -> !selectedVertexState.isSelected(v)) + .collect(Collectors.toSet()); } private Set getAllDownstreamVerticesFromSelected() { @@ -895,10 +895,10 @@ public class DefaultGraphDisplay implements GraphDisplay { if (viewer.getComponent().isVisible() && !viewer.getBounds().isEmpty()) { // project the view bounds into the layout coordinate system, test for containing the coordinates return viewer.getRenderContext() - .getMultiLayerTransformer() - .inverseTransform(viewer.getBounds()) - .getBounds() - .contains(x, y); + .getMultiLayerTransformer() + .inverseTransform(viewer.getBounds()) + .getBounds() + .contains(x, y); } return true; } @@ -987,8 +987,6 @@ public class DefaultGraphDisplay implements GraphDisplay { private void setInitialLayoutAlgorithm() { String layoutAlgorithmName = graphDisplayOptions.getDefaultLayoutAlgorithmNameLayout(); layoutAction.setCurrentActionStateByUserData(layoutAlgorithmName); - TaskLauncher - .launch(new SetLayoutTask(viewer, layoutTransitionManager, layoutAlgorithmName)); } /** @@ -998,6 +996,11 @@ public class DefaultGraphDisplay implements GraphDisplay { * @return true if the vertex is a root */ private boolean isRoot(AttributedVertex vertex) { + // Prevent the exception thrown by the graphing library if the given node is not in the + // graph. This can happen during graph transitions. + if (!graph.containsVertex(vertex)) { + return false; + } Set incomingEdgesOf = graph.incomingEdgesOf(vertex); return incomingEdgesOf.isEmpty() || graph.incomingEdgesOf(vertex).equals(graph.outgoingEdgesOf(vertex)); @@ -1010,37 +1013,37 @@ public class DefaultGraphDisplay implements GraphDisplay { Set vertices = graph.vertexSet(); Set edges = graph.edgeSet(); vertexFilters = AttributeFilters.builder() - .exclude(Set.of("Address", "Code", "Name")) - .elements(vertices) - .maxFactor(.05) - .buttonSupplier(JRadioButton::new) - .paintFunction(v -> Colors.FOREGROUND) - .build(); + .exclude(Set.of("Address", "Code", "Name")) + .elements(vertices) + .maxFactor(.05) + .buttonSupplier(JRadioButton::new) + .paintFunction(v -> Colors.FOREGROUND) + .build(); vertexFilters.addItemListener(item -> { @SuppressWarnings("unchecked") Set selected = (Set) item.getItem(); viewer.getRenderContext() - .setVertexIncludePredicate( - v -> v.getAttributes().values().stream().noneMatch(selected::contains)); + .setVertexIncludePredicate( + v -> v.getAttributes().values().stream().noneMatch(selected::contains)); viewer.repaint(); }); edgeFilters = AttributeFilters.builder() - .exclude(Set.of("*ToKey", "*FromKey", "Address", "Name")) - .elements(edges) - .maxFactor(.01) - .buttonSupplier(JRadioButton::new) - .paintFunction(e -> Colors.FOREGROUND) - .build(); + .exclude(Set.of("*ToKey", "*FromKey", "Address", "Name")) + .elements(edges) + .maxFactor(.01) + .buttonSupplier(JRadioButton::new) + .paintFunction(e -> Colors.FOREGROUND) + .build(); edgeFilters.addItemListener(item -> { @SuppressWarnings("unchecked") Set selected = (Set) item.getItem(); viewer.getRenderContext() - .setEdgeIncludePredicate( - e -> e.getAttributes().values().stream().noneMatch(selected::contains)); + .setEdgeIncludePredicate( + e -> e.getAttributes().values().stream().noneMatch(selected::contains)); viewer.repaint(); }); } @@ -1062,8 +1065,8 @@ public class DefaultGraphDisplay implements GraphDisplay { if (vertexCount < 100) { viewer.getVisualizationModel() - .getLayoutModel() - .setPreferredSize(viewSize.width, viewSize.height); + .getLayoutModel() + .setPreferredSize(viewSize.width, viewSize.height); } else { int newSize = viewSize.width + 5 * (vertexCount - 100); @@ -1148,8 +1151,8 @@ public class DefaultGraphDisplay implements GraphDisplay { Point2D newCenter = getPointToCenter(vertices); if (!isVisible(newCenter.getX(), newCenter.getY())) { Point2D existingCenter = viewer.getRenderContext() - .getMultiLayerTransformer() - .inverseTransform(viewer.getCenter()); + .getMultiLayerTransformer() + .inverseTransform(viewer.getCenter()); jobRunner.schedule(new CenterAnimationJob(viewer, existingCenter, newCenter)); } } @@ -1212,12 +1215,12 @@ public class DefaultGraphDisplay implements GraphDisplay { protected VisualizationViewer createViewer() { VisualizationViewer vv = VisualizationViewer. builder() - .multiSelectionStrategySupplier( - () -> freeFormSelection ? MultiSelectionStrategy.arbitrary() - : MultiSelectionStrategy.rectangular()) - .viewSize(PREFERRED_VIEW_SIZE) - .layoutSize(PREFERRED_LAYOUT_SIZE) - .build(); + .multiSelectionStrategySupplier( + () -> freeFormSelection ? MultiSelectionStrategy.arbitrary() + : MultiSelectionStrategy.rectangular()) + .viewSize(PREFERRED_VIEW_SIZE) + .layoutSize(PREFERRED_LAYOUT_SIZE) + .build(); // Add an ancestor listener to scale and center the graph after the component // has been initially shown. @@ -1300,7 +1303,6 @@ public class DefaultGraphDisplay implements GraphDisplay { @Override public void addAction(DockingActionIf action) { - if (containsAction(action)) { Msg.warn(this, "Action with same name and owner already exixts in graph: " + action.getFullName()); @@ -1359,7 +1361,7 @@ public class DefaultGraphDisplay implements GraphDisplay { } else if (hideSelected) { viewer.getRenderContext() - .setVertexIncludePredicate(Predicate.not(selectedVertexState::isSelected)); + .setVertexIncludePredicate(Predicate.not(selectedVertexState::isSelected)); } else if (hideUnselected) { viewer.getRenderContext().setVertexIncludePredicate(selectedVertexState::isSelected); @@ -1380,14 +1382,12 @@ public class DefaultGraphDisplay implements GraphDisplay { * new graph which may add its own set of actions for that particular graph. */ void restoreToDefaultSetOfActions() { - Swing.runLater(() -> { - // remove all actions - componentProvider.removeAllLocalActions(); - addedActions.clear(); - // put the standard graph actions back - createToolbarActions(); - createPopupActions(); - }); + // remove all actions + componentProvider.removeAllLocalActions(); + addedActions.clear(); + // put the standard graph actions back + createToolbarActions(); + createPopupActions(); } @Override diff --git a/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphDisplayProvider.java b/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphDisplayProvider.java index f8ed48e9e0..d110fafeff 100644 --- a/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphDisplayProvider.java +++ b/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphDisplayProvider.java @@ -21,8 +21,7 @@ import java.util.stream.Collectors; import ghidra.framework.options.Options; import ghidra.framework.options.PreferenceState; import ghidra.framework.plugintool.PluginTool; -import ghidra.service.graph.GraphDisplay; -import ghidra.service.graph.GraphDisplayProvider; +import ghidra.service.graph.*; import ghidra.util.HelpLocation; import ghidra.util.Swing; import ghidra.util.task.TaskMonitor; @@ -53,14 +52,15 @@ public class DefaultGraphDisplayProvider implements GraphDisplayProvider { @Override public GraphDisplay getGraphDisplay(boolean reuseGraph, TaskMonitor monitor) { - - if (reuseGraph && !displays.isEmpty()) { - DefaultGraphDisplay visibleGraph = (DefaultGraphDisplay) getActiveGraphDisplay(); - visibleGraph.restoreToDefaultSetOfActions(); - return visibleGraph; - } - return Swing.runNow(() -> { + if (reuseGraph && !displays.isEmpty()) { + DefaultGraphDisplay visibleGraph = (DefaultGraphDisplay) getActiveGraphDisplay(); + visibleGraph.setGraph(new AttributedGraph("Empty", null), + new DefaultGraphDisplayOptions(), "", false, monitor); + visibleGraph.restoreToDefaultSetOfActions(); + return visibleGraph; + } + DefaultGraphDisplay display = new DefaultGraphDisplay(this, displayCounter++); displays.add(display); return display; @@ -79,8 +79,8 @@ public class DefaultGraphDisplayProvider implements GraphDisplayProvider { public List getAllGraphDisplays() { return Swing.runNow(() -> { return displays.stream() - .sorted((d1, d2) -> -(d1.getId() - d2.getId())) // largest/newest IDs come first - .collect(Collectors.toList()); + .sorted((d1, d2) -> -(d1.getId() - d2.getId())) // largest/newest IDs come first + .collect(Collectors.toList()); }); }