8294565: IGV: ClassCastException when clicking on an edge in the graph

Reviewed-by: rcastanedalo, thartmann
This commit is contained in:
Tobias Holenstein 2022-10-24 14:17:33 +00:00
parent 3898385788
commit c055dfc3ce
2 changed files with 73 additions and 70 deletions

View File

@ -723,50 +723,52 @@ public class DiagramScene extends ObjectScene implements DiagramViewer {
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);
@ -782,7 +784,7 @@ public class DiagramScene extends ObjectScene implements DiagramViewer {
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);
@ -796,44 +798,42 @@ public class DiagramScene extends ObjectScene implements DiagramViewer {
}
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;
@ -855,9 +855,9 @@ public class DiagramScene extends ObjectScene implements DiagramViewer {
}
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;
@ -874,7 +874,7 @@ public class DiagramScene extends ObjectScene implements DiagramViewer {
lineWidget.getActions().addAction(hoverAction);
}
processOutputSlot(lastLineCache, outputSlot, connectionList, controlPointIndex + 1, p, newPredecessor, offx, offy, animator);
processOutputSlot(lastLineCache, outputSlot, connectionList, controlPointIndex + 1, currentPoint, newPredecessor, animator);
}
}

View File

@ -27,8 +27,10 @@ import com.sun.hotspot.igv.graph.Block;
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;
@ -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);
@ -107,14 +108,15 @@ public class LineWidget extends Widget implements PopupMenuProvider {
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 {
@ -122,28 +124,28 @@ public class LineWidget extends Widget implements PopupMenuProvider {
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);
}
}));
}
@ -209,6 +211,7 @@ public class LineWidget extends Widget implements PopupMenuProvider {
for (LineWidget w : successors) {
if (w.getFrom().equals(getTo())) {
sameTo = true;
break;
}
}