Merge remote-tracking branch 'origin/GP-0_ghidravore_graph_test_failure--SQUASHED'

This commit is contained in:
ghidravore 2021-08-18 12:33:18 -04:00
commit 48cdbc2cb1
6 changed files with 149 additions and 75 deletions

View File

@ -94,7 +94,6 @@ public class DefaultGraphDisplay implements GraphDisplay {
private static final String ACTION_OWNER = "GraphServices";
private static final int MAX_NODES = Integer.getInteger("maxNodes", 10000);
private static final Dimension PREFERRED_VIEW_SIZE = new Dimension(1000, 1000);
private static final Dimension PREFERRED_LAYOUT_SIZE = new Dimension(3000, 3000);
@ -273,16 +272,16 @@ public class DefaultGraphDisplay implements GraphDisplay {
Lens lens = Lens.builder().lensShape(Lens.Shape.RECTANGLE).magnification(3.f).build();
lens.setMagnification(2.f);
LensMagnificationGraphMousePlugin magnificationPlugin =
new LensMagnificationGraphMousePlugin(1.f, 60.f, .2f) {
// Override to address a bug when using a high resolution mouse wheel.
// May be removed when jungrapht-visualization version is updated
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (e.getWheelRotation() != 0) {
super.mouseWheelMoved(e);
}
new LensMagnificationGraphMousePlugin(1.f, 60.f, .2f) {
// Override to address a bug when using a high resolution mouse wheel.
// May be removed when jungrapht-visualization version is updated
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (e.getWheelRotation() != 0) {
super.mouseWheelMoved(e);
}
};
}
};
MutableTransformer transformer = viewer.getRenderContext()
.getMultiLayerTransformer()
@ -1158,9 +1157,10 @@ public class DefaultGraphDisplay implements GraphDisplay {
this.title = title;
componentProvider.setTitle(title);
int count = graph.getVertexCount();
if (count > MAX_NODES) {
if (count > options.getMaxNodeCount()) {
Msg.showWarn(this, null, "Graph Not Rendered - Too many nodes!",
"Exceeded limit of " + MAX_NODES + " nodes.\n\n Graph contained " + count +
"Exceeded limit of " + options.getMaxNodeCount() + " nodes.\n\n Graph contained " +
count +
" nodes!");
graph = new AttributedGraph("Aborted", graph.getGraphType(), "Too Many Nodes");
graph.addVertex("1", "Graph Aborted");

View File

@ -47,8 +47,18 @@ public class DefaultGraphRenderer implements GraphRenderer {
private static final double ARROW_WIDTH_TO_LENGTH_RATIO = 1.3;
private static final int DEFAULT_MARGIN_BORDER_SIZE = 4;
private static final int DEFAULT_STROKE_THICKNESS = 6;
// scale factor so the icons can be rendered smaller so that fonts read better when zoomed out a bit
private static final int ICON_ZOOM = 5;
// This is an arbitrary scale factor applied after creating a node's icon
// This somehow causes the low level jungrapht layout to perform better
// If the icon is not zoomed, the icons are rendered too small and too far apart
// somehow, by giving it bigger icons, the layouts seem to produce better results
// When/if this is fixed in the jungrapht library, this can be removed
private static final int ICON_ZOOM = 2;
// put a limit on node size. Nodes are sized based on user supplied vertex names, so need to
// protect them from becoming too large, so just picked some limits.
private static final int MAX_WIDTH = 500;
private static final int MAX_HEIGHT = 500;
private int labelBorderSize = DEFAULT_MARGIN_BORDER_SIZE;
private int strokeThickness = DEFAULT_STROKE_THICKNESS;
@ -220,7 +230,6 @@ public class DefaultGraphRenderer implements GraphRenderer {
VertexShape vertexShape = options.getVertexShape(vertex);
Color vertexColor = options.getVertexColor(vertex);
String labelText = options.getVertexLabel(vertex);
return createImage(vertexShape, labelText, vertexColor);
}
@ -235,37 +244,47 @@ public class DefaultGraphRenderer implements GraphRenderer {
Shape unitShape = vertexShape.getShape();
Rectangle bounds = unitShape.getBounds();
// this variable attempts to keep the shape's height from being too out of proportion
// from the width.
int maxWidthToHeightRatio = vertexShape.getMaxWidthToHeightRatio();
double sizeFactor = vertexShape.getShapeToLabelRatio();
int labelWidth = label.getWidth();
int labelHeight = label.getHeight();
int iconWidth =
(int) (Math.max(labelWidth, labelHeight * 2.0) * sizeFactor) + strokeThickness;
int iconHeight =
(int) (Math.max(label.getHeight(), labelWidth / maxWidthToHeightRatio) * sizeFactor) +
strokeThickness;
// make height somewhat bigger if label width is really long to avoid really long thin
// nodes
labelHeight = Math.max(labelHeight, labelWidth / maxWidthToHeightRatio);
double scalex = iconWidth / bounds.getWidth();
double scaley = iconHeight / bounds.getHeight();
// adjust for shape size factor (some shapes want to be somewhat bigger than the label)
// for example, triangles need to be much bigger to get the text to fit inside the shape,
// whereas, rectangles fit naturally.
int shapeWidth = (int) (labelWidth * sizeFactor);
int shapeHeight = (int) (labelHeight * sizeFactor);
// compute the amount to scale the shape to fit around the label
double scalex = shapeWidth / bounds.getWidth();
double scaley = shapeHeight / bounds.getHeight();
Shape scaledShape =
AffineTransform.getScaleInstance(scalex, scaley).createTransformedShape(unitShape);
// this determines the vertical positioning of text in the shape
// a value of 0 will put the text at the top, 1 at the bottom, and .5 in the center
double labelOffsetRatio = vertexShape.getLabelPosition();
bounds = scaledShape.getBounds();
int iconWidth = bounds.width + (2 * strokeThickness);
int iconHeight = bounds.height + (2 * strokeThickness);
int width = bounds.width + 2 * strokeThickness;
int height = bounds.height + strokeThickness;
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
BufferedImage bufferedImage =
new BufferedImage(iconWidth, iconHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = bufferedImage.createGraphics();
graphics.setRenderingHints(renderingHints);
AffineTransform graphicsTransform = graphics.getTransform();
graphics.translate(-bounds.x + strokeThickness, -bounds.y + strokeThickness / 2);
// shapes are centered at the origin, so translate the graphics to compensate
graphics.translate(-bounds.x + strokeThickness, -bounds.y + strokeThickness);
graphics.setPaint(Color.WHITE);
graphics.fill(scaledShape);
graphics.setPaint(vertexColor);
@ -273,8 +292,12 @@ public class DefaultGraphRenderer implements GraphRenderer {
graphics.draw(scaledShape);
graphics.setTransform(graphicsTransform);
int xOffset = (width - label.getWidth()) / 2;
int yOffset = (int) ((height - label.getHeight()) * labelOffsetRatio);
// center the text horizontally
// position the text vertically based on the shape.
int xOffset = (iconWidth - label.getWidth()) / 2;
int yOffset = (int) ((iconHeight - label.getHeight()) * labelOffsetRatio);
graphics.translate(xOffset, yOffset);
graphics.setPaint(Color.black);
label.paint(graphics);
@ -282,19 +305,26 @@ public class DefaultGraphRenderer implements GraphRenderer {
graphics.setTransform(graphicsTransform); // restore the original transform
graphics.dispose();
Image scaledImage =
ImageUtils.createScaledImage(bufferedImage, width * ICON_ZOOM, height * ICON_ZOOM,
ImageUtils.createScaledImage(bufferedImage, iconWidth * ICON_ZOOM,
iconHeight * ICON_ZOOM,
Image.SCALE_FAST);
ImageIcon imageIcon = new ImageIcon(scaledImage);
return imageIcon;
}
private void prepareLabel(String vertexName, Color vertexColor) {
label.setFont(options.getFont());
// The label is just used as a renderer and never parented, so no need to be
// on the swing thread
Font font = options.getFont();
label.setFont(font);
label.setText(vertexName);
Dimension labelSize = label.getPreferredSize();
label.setSize(labelSize);
// make sure the the vertexName doesn't make the icon ridiculously big
int width = Math.min(labelSize.width, MAX_WIDTH);
int height = Math.min(labelSize.height, MAX_HEIGHT);
label.setSize(width, height);
}
@Override

View File

@ -39,10 +39,10 @@ import ghidra.util.bean.opteditor.OptionsVetoException;
* and edge type and shapes for vertex types.
*/
public class GraphDisplayOptions implements OptionsChangeListener {
public static final GraphDisplayOptions DEFAULT =
new GraphDisplayOptions(new EmptyGraphType());
private static final String FONT = "Font";
private static final String LABEL_POSITION = "Label Position";
private static final String USE_ICONS = "Use Icons";
@ -50,7 +50,7 @@ public class GraphDisplayOptions implements OptionsChangeListener {
private static final String EDGE_COLORS = "Edge Colors";
private static final String VERTEX_COLORS = "Vertex Colors";
private static final String VERTEX_SHAPES = "Vertex Shapes";
private static final String MISCELLANIOUS_OPTIONS = "Miscellanious";
private static final String MISCELLANEOUS_OPTIONS = "Miscellaneous";
private static final String DEFAULT_VERTEX_COLOR = "Default Vertex Color";
private static final String DEFAULT_EDGE_COLOR = "Default Edge Color";
private static final String DEFAULT_VERTEX_SHAPE = "Default Vertex Shape";
@ -58,6 +58,8 @@ public class GraphDisplayOptions implements OptionsChangeListener {
private static final String VERTEX_SELECTION_COLOR = "Selected Vertex Color";
private static final String EDGE_SELECTION_COLOR = "Selected Edge Color";
private static final String MAX_NODES_SIZE = "Max Graph Size";
private GraphType graphType;
private Map<String, Color> vertexColorMap = new HashMap<>();
@ -85,6 +87,8 @@ public class GraphDisplayOptions implements OptionsChangeListener {
private Font font = new Font("Dialog", Font.BOLD, 18);
private int arrowLength = 15;
private int maxNodeCount = 500; // graph display struggles with too many nodes
/**
* Constructs a new GraphTypeDisplayOptions for the given {@link GraphType}
* @param graphType The {@link GraphType} for which to define display options
@ -139,8 +143,6 @@ public class GraphDisplayOptions implements OptionsChangeListener {
changeListeners.remove(listener);
}
/**
* Sets the default shape to be used by vertices that don't have a vertex type set
* @param shape the default vertex shape
@ -384,7 +386,6 @@ public class GraphDisplayOptions implements OptionsChangeListener {
vertexShapeMap.put(vertexType, Objects.requireNonNull(vertexShape));
}
/**
* Returns the color for the given edge type
* @param edgeType the edge type whose color is to be determined.
@ -579,6 +580,24 @@ public class GraphDisplayOptions implements OptionsChangeListener {
this.arrowLength = length;
}
/**
* Returns the maximum number of nodes that can be in a displayed graph
* @return the maximum number of nodes that can be in a displayed graph
*/
public int getMaxNodeCount() {
return maxNodeCount;
}
/**
* Sets the maximum number of nodes a graph can have and still be displayed. Be careful,
* setting this value too high can result in Ghidra running out of memory and/or
* making the system very sluggish.
* @param maxNodeCount the maximum number of nodes a graph can have and still be displayed.
*/
public void setMaxNodeCount(int maxNodeCount) {
this.maxNodeCount = maxNodeCount;
}
/**
* Returns true if this {@link GraphDisplayOptions} instance has been constructed with
* a tool for getting/saving option values in the tool options
@ -603,7 +622,7 @@ public class GraphDisplayOptions implements OptionsChangeListener {
registerVertexColorOptions(rootOptions, help);
registerVertexShapeOptions(rootOptions, help);
registerEdgeColorOptions(rootOptions, help);
registerMiscellaniousOptions(rootOptions, help);
registerMiscellaneousOptions(rootOptions, help);
}
/**
@ -643,7 +662,6 @@ public class GraphDisplayOptions implements OptionsChangeListener {
registeredWithTool = true;
}
private void updateOptions(Options rootOptions) {
updateVertexColorsFromOptions(rootOptions);
updateEdgeColorsFromOptions(rootOptions);
@ -652,7 +670,7 @@ public class GraphDisplayOptions implements OptionsChangeListener {
}
private void updateMiscellaniousOptions(Options rootOptions) {
Options options = rootOptions.getOptions(MISCELLANIOUS_OPTIONS);
Options options = rootOptions.getOptions(MISCELLANEOUS_OPTIONS);
String shapeName = options.getString(DEFAULT_VERTEX_SHAPE, defaultVertexShape.getName());
defaultVertexShape = VertexShape.getShape(shapeName);
@ -662,13 +680,14 @@ public class GraphDisplayOptions implements OptionsChangeListener {
vertexSelectionColor = options.getColor(VERTEX_SELECTION_COLOR, vertexSelectionColor);
edgeSelectionColor = options.getColor(EDGE_SELECTION_COLOR, edgeSelectionColor);
defaultLayoutAlgorithmName =
options.getString(DEFAULT_LAYOUT_ALGORITHM, defaultLayoutAlgorithmName);
useIcons = options.getBoolean(USE_ICONS, useIcons);
labelPosition = options.getEnum(LABEL_POSITION, labelPosition);
font = options.getFont(FONT, font);
maxNodeCount = options.getInt(MAX_NODES_SIZE, maxNodeCount);
}
private void updateVertexShapesFromOptions(Options rootOptions) {
@ -713,7 +732,6 @@ public class GraphDisplayOptions implements OptionsChangeListener {
}
}
private void registerVertexColorOptions(Options rootOptions, HelpLocation help) {
Options options = rootOptions.getOptions(VERTEX_COLORS);
@ -755,10 +773,12 @@ public class GraphDisplayOptions implements OptionsChangeListener {
options.registerOptionsEditor(editor);
}
private void registerMiscellaniousOptions(Options rootOptions, HelpLocation help) {
private void registerMiscellaneousOptions(Options rootOptions, HelpLocation help) {
Options options = rootOptions.getOptions(MISCELLANIOUS_OPTIONS);
Options options = rootOptions.getOptions(MISCELLANEOUS_OPTIONS);
options.registerOption(MAX_NODES_SIZE, OptionType.INT_TYPE, maxNodeCount, help,
"Graphs with more than this number of nodes will not be displayed. (Large graphs can cause Ghidra to become unstable/sluggish)");
StringWithChoicesEditor editor = new StringWithChoicesEditor(VertexShape.getShapeNames());
options.registerOption(VERTEX_SELECTION_COLOR, OptionType.COLOR_TYPE, vertexSelectionColor,
@ -777,9 +797,12 @@ public class GraphDisplayOptions implements OptionsChangeListener {
options.registerOption(DEFAULT_EDGE_COLOR, OptionType.COLOR_TYPE, defaultEdgeColor,
help, "Color for edge that have no edge type defined");
editor = new StringWithChoicesEditor(graphType.getEdgeTypes());
options.registerOption(FAVORED_EDGE_TYPE, OptionType.STRING_TYPE, favoredEdgeType, help,
"Favored edge is used to influence layout algorithms", editor);
List<String> edgeTypes = graphType.getEdgeTypes();
if (!edgeTypes.isEmpty()) {
editor = new StringWithChoicesEditor(edgeTypes);
options.registerOption(FAVORED_EDGE_TYPE, OptionType.STRING_TYPE, favoredEdgeType, help,
"Favored edge is used to influence layout algorithms", editor);
}
editor = new StringWithChoicesEditor(LayoutAlgorithmNames.getLayoutAlgorithmNames());
options.registerOption(DEFAULT_LAYOUT_ALGORITHM, OptionType.STRING_TYPE,
@ -796,6 +819,7 @@ public class GraphDisplayOptions implements OptionsChangeListener {
List<String> optionNamesInDisplayOrder = new ArrayList<>();
optionNamesInDisplayOrder.add(MAX_NODES_SIZE);
optionNamesInDisplayOrder.add(VERTEX_SELECTION_COLOR);
optionNamesInDisplayOrder.add(EDGE_SELECTION_COLOR);
optionNamesInDisplayOrder.add(DEFAULT_VERTEX_COLOR);
@ -807,9 +831,8 @@ public class GraphDisplayOptions implements OptionsChangeListener {
optionNamesInDisplayOrder.add(FONT);
optionNamesInDisplayOrder.add(USE_ICONS);
OptionsEditor optionsEditor =
new ScrollableOptionsEditor(MISCELLANIOUS_OPTIONS, optionNamesInDisplayOrder);
new ScrollableOptionsEditor(MISCELLANEOUS_OPTIONS, optionNamesInDisplayOrder);
options.registerOptionsEditor(optionsEditor);
}
@ -827,5 +850,5 @@ public class GraphDisplayOptions implements OptionsChangeListener {
"\" not defined in GraphType \"" + getGraphType().getName() + "\".");
}
}
}
}

View File

@ -26,7 +26,7 @@ public class GraphDisplayOptionsBuilder {
private GraphDisplayOptions displayOptions;
/**
* Create a new {@link GraphDisplayOptionsBuilder}
* Create a new GraphDisplayOptionsBuilder
* @param graphType the {@link GraphType} of graphs that this instance configures.
*/
public GraphDisplayOptionsBuilder(GraphType graphType) {
@ -36,7 +36,7 @@ public class GraphDisplayOptionsBuilder {
/**
* Sets the default vertex color for vertexes that don't have a registered vertex type
* @param c the default vertex color
* @return this {@link GraphDisplayOptionsBuilder}
* @return this GraphDisplayOptionsBuilder
*/
public GraphDisplayOptionsBuilder defaultVertexColor(Color c) {
displayOptions.setDefaultVertexColor(c);
@ -46,7 +46,7 @@ public class GraphDisplayOptionsBuilder {
/**
* Sets the default edge color for edges that don't have a registered edge type
* @param c the default edge color
* @return this {@link GraphDisplayOptionsBuilder}
* @return this GraphDisplayOptionsBuilder
*/
public GraphDisplayOptionsBuilder defaultEdgeColor(Color c) {
Objects.requireNonNull(c);
@ -57,7 +57,7 @@ public class GraphDisplayOptionsBuilder {
/**
* Sets the vertex selection color
* @param color the vertex selection color
* @return this {@link GraphDisplayOptionsBuilder}
* @return this GraphDisplayOptionsBuilder
*/
public GraphDisplayOptionsBuilder vertexSelectionColor(Color color) {
displayOptions.setVertexSelectionColor(color);
@ -67,7 +67,7 @@ public class GraphDisplayOptionsBuilder {
/**
* Sets the edge selection color
* @param color the edge selection color
* @return this {@link GraphDisplayOptionsBuilder}
* @return this GraphDisplayOptionsBuilder
*/
public GraphDisplayOptionsBuilder edgeSelectionColor(Color color) {
displayOptions.setEdgeSelectionColor(color);
@ -77,7 +77,7 @@ public class GraphDisplayOptionsBuilder {
/**
* Sets the default vertex shape for vertices that don't have a registered vertex type
* @param vertexShape the {@link VertexShape} to use as a default
* @return this {@link GraphDisplayOptionsBuilder}
* @return this GraphDisplayOptionsBuilder
*/
public GraphDisplayOptionsBuilder defaultVertexShape(VertexShape vertexShape) {
Objects.requireNonNull(vertexShape);
@ -90,7 +90,7 @@ public class GraphDisplayOptionsBuilder {
* @param vertexType the vertex type to assign shape and color
* @param vertexShape the shape to use for the named vertex type
* @param color the color to use for the named vertex type
* @return this {@link GraphDisplayOptionsBuilder}
* @return this GraphDisplayOptionsBuilder
*/
public GraphDisplayOptionsBuilder vertex(String vertexType, VertexShape vertexShape,
Color color) {
@ -102,7 +102,7 @@ public class GraphDisplayOptionsBuilder {
* Sets the color for edges of the given type
* @param edgeType the edge type to assign color
* @param color the color to use for the named edge type
* @return this {@link GraphDisplayOptionsBuilder}
* @return this GraphDisplayOptionsBuilder
*/
public GraphDisplayOptionsBuilder edge(String edgeType, Color color) {
displayOptions.configureEdgeType(edgeType, color);
@ -112,7 +112,7 @@ public class GraphDisplayOptionsBuilder {
/**
* Sets the attribute used to override the color for a vertex
* @param colorAttributeKey the attribute key to use for overriding a vertex color
* @return this {@link GraphDisplayOptionsBuilder}
* @return this GraphDisplayOptionsBuilder
*/
public GraphDisplayOptionsBuilder vertexColorOverrideAttribute(String colorAttributeKey) {
displayOptions.setVertexColorOverrideAttributeKey(colorAttributeKey);
@ -122,7 +122,7 @@ public class GraphDisplayOptionsBuilder {
/**
* Sets the attribute used to override the color for a edge
* @param colorAttributeKey the attribute key to use for overriding an edge color
* @return this {@link GraphDisplayOptionsBuilder}
* @return this GraphDisplayOptionsBuilder
*/
public GraphDisplayOptionsBuilder edgeColorOverrideAttribute(String colorAttributeKey) {
displayOptions.setEdgeColorOverrideAttributeKey(colorAttributeKey);
@ -132,7 +132,7 @@ public class GraphDisplayOptionsBuilder {
/**
* Sets the attribute used to override the shape for a vertex
* @param shapeAttributeKey the attribute key to use of shape override
* @return this {@link GraphDisplayOptionsBuilder}
* @return this GraphDisplayOptionsBuilder
*/
public GraphDisplayOptionsBuilder shapeOverrideAttribute(String shapeAttributeKey) {
displayOptions.setVertexShapeOverrideAttributeKey(shapeAttributeKey);
@ -142,7 +142,7 @@ public class GraphDisplayOptionsBuilder {
/**
* Sets the name of the layout algorithm that will be used to initially layout the graph
* @param string the name of the layout algoritm to use to initially layout the graph
* @return this {@link GraphDisplayOptionsBuilder}
* @return this GraphDisplayOptionsBuilder
*/
public GraphDisplayOptionsBuilder defaultLayoutAlgorithm(String string) {
displayOptions.setDefaultLayoutAlgorithmName(string);
@ -154,7 +154,7 @@ public class GraphDisplayOptionsBuilder {
* cached images with the label inside the shapes. If false, vertices are drawn as smaller
* shapes with labels drawn near the shapes.
* @param b true to use pre-rendered icon images
* @return this {@link GraphDisplayOptionsBuilder}
* @return this GraphDisplayOptionsBuilder
*/
public GraphDisplayOptionsBuilder useIcons(boolean b) {
displayOptions.setUsesIcons(b);
@ -164,18 +164,28 @@ public class GraphDisplayOptionsBuilder {
/**
* Sets the length of the arrows to display in the graph. The width will be sized proportionately.
* @param length the length the arrows to display in the graph
* @return this {@link GraphDisplayOptionsBuilder}
* @return this GraphDisplayOptionsBuilder
*/
public GraphDisplayOptionsBuilder arrowLength(int length) {
displayOptions.setArrowLength(length);
return this;
}
/**
* Sets the maximum number of nodes a graph can have and still be displayed.
* @param maxNodeCount the maximum number of nodes
* @return this GraphDisplayOptionsBuilder
*/
public GraphDisplayOptionsBuilder maxNodeCount(int maxNodeCount) {
displayOptions.getMaxNodeCount();
return this;
}
/**
* Sets the vertex label position relative to vertex shape. This is only applicable if the
* {@link #useIcons(boolean)} is set to true.
* {@link #useIcons(boolean)} is set to false.
* @param labelPosition the relative position to place the vertex label
* @return this {@link GraphDisplayOptionsBuilder}
* @return this GraphDisplayOptionsBuilder
*/
public GraphDisplayOptionsBuilder labelPosition(GraphLabelPosition labelPosition) {
displayOptions.setLabelPosition(labelPosition);

View File

@ -37,8 +37,8 @@ public class GraphDisplayOptionsTest {
@Before
public void setUp() {
List<String> vertexTypes = Arrays.asList("V1", "V2", "V3" );
List<String> edgeTypes = Arrays.asList("E1", "E2", "E3" );
List<String> vertexTypes = Arrays.asList("V1", "V2", "V3");
List<String> edgeTypes = Arrays.asList("E1", "E2", "E3");
graphType = new GraphType("Test", "Test Description", vertexTypes, edgeTypes);
options = new GraphDisplayOptions(graphType);
}
@ -217,7 +217,6 @@ public class GraphDisplayOptionsTest {
assertEquals(VertexShape.STAR, options.getVertexShape("V1"));
}
@Test
public void testGetEdgeColorForType() {
assertEquals(options.getDefaultEdgeColor(), options.getEdgeColor("V1"));
@ -252,8 +251,8 @@ public class GraphDisplayOptionsTest {
assertEquals(options.getDefaultEdgeColor(),
edgeColorOptions.getColor("E1", Color.WHITE));
Options miscellaniousOptions = graphDisplayOptions.getOptions("Miscellanious");
leafOptionNames = miscellaniousOptions.getLeafOptionNames();
Options miscellaneousOptions = graphDisplayOptions.getOptions("Miscellaneous");
leafOptionNames = miscellaneousOptions.getLeafOptionNames();
assertEquals(Arrays.asList("Use Icons", "Selected Vertex Color", "Default Layout Algorithm",
"Default Vertex Color", "Default Vertex Shape", "Selected Edge Color", "Label Position",
"Default Edge Color", "Font", "Favored Edge Type"), leafOptionNames);

View File

@ -33,6 +33,7 @@ import ghidra.graph.visualization.GroupVertex;
import ghidra.service.graph.*;
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
import ghidra.test.TestEnv;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
public class GraphActionsTest extends AbstractGhidraHeadedIntegrationTest {
@ -445,7 +446,18 @@ public class GraphActionsTest extends AbstractGhidraHeadedIntegrationTest {
GraphDisplayBroker broker = tool.getService(GraphDisplayBroker.class);
GraphDisplayProvider service = broker.getGraphDisplayProvider("Default Graph Display");
display = service.getGraphDisplay(false, TaskMonitor.DUMMY);
display.setGraph(graph, "test graph", false, TaskMonitor.DUMMY);
GraphDisplayOptions options = new GraphDisplayOptions(graph.getGraphType());
runSwing(() -> {
try {
display.setGraph(graph, options, "test graph", false, TaskMonitor.DUMMY);
}
catch (CancelledException e) {
// can't happen with a dummy monitor
}
});
display.setGraphDisplayListener(new TestGraphDisplayListener("test"));
}