Skip to content

Commit

Permalink
8294565: IGV: ClassCastException when clicking on an edge in the graph
Browse files Browse the repository at this point in the history
Reviewed-by: rcastanedalo, thartmann
  • Loading branch information
tobiasholenstein committed Oct 24, 2022
1 parent 3898385 commit c055dfc
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 70 deletions.
Expand Up @@ -723,50 +723,52 @@ private void doCFGLayout(HashSet<Figure> figures, HashSet<Connection> edges) {

private Set<Pair<Point, Point>> lineCache = new HashSet<>();

private void relayoutWithoutLayout(Set<Widget> oldVisibleWidgets) {

Diagram diagram = getModel().getDiagram();

SceneAnimator animator = getSceneAnimator();
connectionLayer.removeChildren();
private boolean shouldAnimate() {
int visibleFigureCount = 0;
for (Figure f : diagram.getFigures()) {
if (getWidget(f, FigureWidget.class).isVisible()) {
for (Figure figure : getModel().getDiagram().getFigures()) {
if (getWidget(figure, FigureWidget.class).isVisible()) {
visibleFigureCount++;
}
}
return visibleFigureCount <= ANIMATION_LIMIT;
}

private void relayoutWithoutLayout(Set<Widget> oldVisibleWidgets) {
assert oldVisibleWidgets != null;

Diagram diagram = getModel().getDiagram();
connectionLayer.removeChildren();

SceneAnimator connectionAnimator = getSceneAnimator();
boolean doAnimation = shouldAnimate();
if (!doAnimation) {
connectionAnimator = null;
}

Set<Pair<Point, Point>> lastLineCache = lineCache;
lineCache = new HashSet<>();
for (Figure f : diagram.getFigures()) {
for (OutputSlot s : f.getOutputSlots()) {
SceneAnimator anim = animator;
if (visibleFigureCount > ANIMATION_LIMIT || oldVisibleWidgets == null) {
anim = null;
}
List<Connection> cl = new ArrayList<>(s.getConnections().size());
for (FigureConnection c : s.getConnections()) {
cl.add((Connection) c);
}
processOutputSlot(lastLineCache, s, cl, 0, null, null, 0, 0, anim);
for (Figure figure : diagram.getFigures()) {
for (OutputSlot outputSlot : figure.getOutputSlots()) {
List<Connection> connectionList = new ArrayList<>(outputSlot.getConnections());
processOutputSlot(lastLineCache, outputSlot, connectionList, 0, null, null, connectionAnimator);
}
}

if (getModel().getShowCFG()) {
for (BlockConnection c : diagram.getBlockConnections()) {
if (isVisible(c)) {
processOutputSlot(lastLineCache, null, Collections.singletonList(c), 0, null, null, 0, 0, animator);
processOutputSlot(lastLineCache, null, Collections.singletonList(c), 0, null, null, connectionAnimator);
}
}
}

SceneAnimator animator = getSceneAnimator();
for (Figure f : diagram.getFigures()) {
FigureWidget w = getWidget(f);
if (w.isVisible()) {
Point p = f.getPosition();
Point p2 = new Point(p.x, p.y);
if ((visibleFigureCount <= ANIMATION_LIMIT && oldVisibleWidgets != null && oldVisibleWidgets.contains(w))) {
if (doAnimation && oldVisibleWidgets.contains(w)) {
animator.animatePreferredLocation(w, p2);
} else {
w.setPreferredLocation(p2);
Expand All @@ -782,7 +784,7 @@ private void relayoutWithoutLayout(Set<Widget> oldVisibleWidgets) {
Point location = new Point(b.getBounds().x, b.getBounds().y);
Rectangle r = new Rectangle(location.x, location.y, b.getBounds().width, b.getBounds().height);

if ((visibleFigureCount <= ANIMATION_LIMIT && oldVisibleWidgets != null && oldVisibleWidgets.contains(w))) {
if (doAnimation && oldVisibleWidgets.contains(w)) {
animator.animatePreferredBounds(w, r);
} else {
w.setPreferredBounds(r);
Expand All @@ -796,44 +798,42 @@ private void relayoutWithoutLayout(Set<Widget> oldVisibleWidgets) {
}
private final Point specialNullPoint = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);

private void processOutputSlot(Set<Pair<Point, Point>> lastLineCache, OutputSlot outputSlot, List<Connection> connections, int controlPointIndex, Point lastPoint, LineWidget predecessor, int offx, int offy, SceneAnimator animator) {
private void processOutputSlot(Set<Pair<Point, Point>> lastLineCache, OutputSlot outputSlot, List<Connection> connections, int controlPointIndex, Point lastPoint, LineWidget predecessor, SceneAnimator animator) {
Map<Point, List<Connection>> pointMap = new HashMap<>(connections.size());

for (Connection c : connections) {

if (!isVisible(c)) {
for (Connection connection : connections) {
if (!isVisible(connection)) {
continue;
}

List<Point> controlPoints = c.getControlPoints();
List<Point> controlPoints = connection.getControlPoints();
if (controlPointIndex >= controlPoints.size()) {
continue;
}

Point cur = controlPoints.get(controlPointIndex);
if (cur == null) { // Long connection, has been cut vertically.
cur = specialNullPoint;
} else if (c.hasSlots()) {
Point currentPoint = controlPoints.get(controlPointIndex);
if (currentPoint == null) { // Long connection, has been cut vertically.
currentPoint = specialNullPoint;
} else if (connection.hasSlots()) {
if (controlPointIndex == 0 && !outputSlot.shouldShowName()) {
cur = new Point(cur.x, cur.y - SLOT_OFFSET);
currentPoint = new Point(currentPoint.x, currentPoint.y - SLOT_OFFSET);
} else if (controlPointIndex == controlPoints.size() - 1 &&
!((Slot)c.getTo()).shouldShowName()) {
cur = new Point(cur.x, cur.y + SLOT_OFFSET);
!((Slot)connection.getTo()).shouldShowName()) {
currentPoint = new Point(currentPoint.x, currentPoint.y + SLOT_OFFSET);
}
}

if (pointMap.containsKey(cur)) {
pointMap.get(cur).add(c);
if (pointMap.containsKey(currentPoint)) {
pointMap.get(currentPoint).add(connection);
} else {
List<Connection> newList = new ArrayList<>(2);
newList.add(c);
pointMap.put(cur, newList);
newList.add(connection);
pointMap.put(currentPoint, newList);
}

}

for (Point p : pointMap.keySet()) {
List<Connection> connectionList = pointMap.get(p);
for (Point currentPoint : pointMap.keySet()) {
List<Connection> connectionList = pointMap.get(currentPoint);

boolean isBold = false;
boolean isDashed = true;
Expand All @@ -855,9 +855,9 @@ private void processOutputSlot(Set<Pair<Point, Point>> lastLineCache, OutputSlot
}

LineWidget newPredecessor = predecessor;
if (p != specialNullPoint && lastPoint != specialNullPoint && lastPoint != null) {
Point p1 = new Point(lastPoint.x + offx, lastPoint.y + offy);
Point p2 = new Point(p.x + offx, p.y + offy);
if (currentPoint != specialNullPoint && lastPoint != specialNullPoint && lastPoint != null) {
Point p1 = new Point(lastPoint.x, lastPoint.y);
Point p2 = new Point(currentPoint.x, currentPoint.y);

Pair<Point, Point> curPair = new Pair<>(p1, p2);
SceneAnimator curAnimator = animator;
Expand All @@ -874,7 +874,7 @@ private void processOutputSlot(Set<Pair<Point, Point>> lastLineCache, OutputSlot
lineWidget.getActions().addAction(hoverAction);
}

processOutputSlot(lastLineCache, outputSlot, connectionList, controlPointIndex + 1, p, newPredecessor, offx, offy, animator);
processOutputSlot(lastLineCache, outputSlot, connectionList, controlPointIndex + 1, currentPoint, newPredecessor, animator);
}
}

Expand Down
Expand Up @@ -27,8 +27,10 @@
import com.sun.hotspot.igv.graph.Connection;
import com.sun.hotspot.igv.graph.Figure;
import com.sun.hotspot.igv.graph.OutputSlot;
import com.sun.hotspot.igv.layout.Vertex;
import com.sun.hotspot.igv.util.StringUtils;
import com.sun.hotspot.igv.view.DiagramScene;
import com.sun.hotspot.igv.view.actions.CustomSelectAction;
import java.awt.*;
import java.awt.geom.Line2D;
import java.util.ArrayList;
Expand Down Expand Up @@ -57,20 +59,19 @@ public class LineWidget extends Widget implements PopupMenuProvider {
public final int HOVER_ARROW_SIZE = 8;
public final int BOLD_STROKE_WIDTH = 2;
public final int HOVER_STROKE_WIDTH = 3;
private static double ZOOM_FACTOR = 0.1;
private OutputSlot outputSlot;
private DiagramScene scene;
private List<Connection> connections;
private Point from;
private Point to;
private Rectangle clientArea;
private Color color = Color.BLACK;
private LineWidget predecessor;
private List<LineWidget> successors;
private final static double ZOOM_FACTOR = 0.1;
private final OutputSlot outputSlot;
private final DiagramScene scene;
private final List<Connection> connections;
private final Point from;
private final Point to;
private final Rectangle clientArea;
private final LineWidget predecessor;
private final List<LineWidget> successors;
private boolean highlighted;
private boolean popupVisible;
private boolean isBold;
private boolean isDashed;
private final boolean isBold;
private final boolean isDashed;

public LineWidget(DiagramScene scene, OutputSlot s, List<Connection> connections, Point from, Point to, LineWidget predecessor, SceneAnimator animator, boolean isBold, boolean isDashed) {
super(scene);
Expand Down Expand Up @@ -107,43 +108,44 @@ public LineWidget(DiagramScene scene, OutputSlot s, List<Connection> connections
clientArea = new Rectangle(minX, minY, maxX - minX + 1, maxY - minY + 1);
clientArea.grow(BORDER, BORDER);

Color color = Color.BLACK;
if (connections.size() > 0) {
color = connections.get(0).getColor();
}
this.setToolTipText("<HTML>" + generateToolTipText(this.connections) + "</HTML>");
setToolTipText("<HTML>" + generateToolTipText(this.connections) + "</HTML>");

this.setCheckClipping(true);
setCheckClipping(true);

this.getActions().addAction(ActionFactory.createPopupMenuAction(this));
getActions().addAction(ActionFactory.createPopupMenuAction(this));
if (animator == null) {
this.setBackground(color);
} else {
this.setBackground(Color.WHITE);
animator.animateBackgroundColor(this, color);
}

this.getActions().addAction(ActionFactory.createSelectAction(new SelectProvider() {
getActions().addAction(new CustomSelectAction(new SelectProvider() {

@Override
public boolean isAimingAllowed(Widget arg0, Point arg1, boolean arg2) {
public boolean isAimingAllowed(Widget widget, Point localLocation, boolean invertSelection) {
return true;
}

@Override
public boolean isSelectionAllowed(Widget arg0, Point arg1, boolean arg2) {
public boolean isSelectionAllowed(Widget widget, Point localLocation, boolean invertSelection) {
return true;
}

@Override
public void select(Widget arg0, Point arg1, boolean arg2) {
Set<Figure> set = new HashSet<>();
for (Connection c : LineWidget.this.connections) {
if (c.hasSlots()) {
set.add(scene.getWidget(c.getTo()));
set.add(scene.getWidget(c.getFrom()));
public void select(Widget widget, Point localLocation, boolean invertSelection) {
Set<Vertex> vertexSet = new HashSet<>();
for (Connection connection : connections) {
if (connection.hasSlots()) {
vertexSet.add(connection.getTo().getVertex());
vertexSet.add(connection.getFrom().getVertex());
}
}
LineWidget.this.scene.setSelectedObjects(set);
scene.userSelectionSuggested(vertexSet, invertSelection);
}
}));
}
Expand Down Expand Up @@ -209,6 +211,7 @@ protected void paintWidget() {
for (LineWidget w : successors) {
if (w.getFrom().equals(getTo())) {
sameTo = true;
break;
}
}

Expand Down

1 comment on commit c055dfc

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.