# HG changeset patch # User Thomas Wuerthinger # Date 1426948898 -3600 # Node ID 3c78119de0cd27c42b3c87db5e89ca77a66de770 # Parent b5516d27d657b854962a8c71eee2d08170b6a834 Layout and display improvements and bug fixes for IdealGraphVisualizer. diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java Sat Mar 21 15:41:38 2015 +0100 @@ -86,7 +86,7 @@ this.to = to; this.state = State.SAME; this.label = label; - this.type = type; + this.type = type.intern(); } static WeakHashMap> immutableCache = new WeakHashMap<>(); diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java Sat Mar 21 15:41:38 2015 +0100 @@ -271,7 +271,7 @@ } else { sb.append(", "); } - sb.append(p[0] + "=" + p[1]); + sb.append(p[0]).append("=").append(p[1]); } return sb.append("]").toString(); } diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java Sat Mar 21 15:41:38 2015 +0100 @@ -706,7 +706,8 @@ private void parseNodes(InputGraph graph) throws IOException { int count = readInt(); Map props = new HashMap<>(); - List edges = new LinkedList<>(); + List inputEdges = new ArrayList<>(count); + List succEdges = new ArrayList<>(count); for (int i = 0; i < count; i++) { int id = readInt(); InputNode node = new InputNode(id); @@ -733,7 +734,7 @@ props.put(key, value); } } - int edgesStart = edges.size(); + ArrayList currentEdges = new ArrayList<>(); int portNum = 0; for (TypedPort p : nodeClass.inputs) { if (p.isList) { @@ -741,14 +742,18 @@ for (int j = 0; j < size; j++) { int in = readInt(); if (in >= 0) { - edges.add(new Edge(in, id, (char) (preds + portNum), p.name + "[" + j + "]", p.type.toString(Length.S), true)); + Edge e = new Edge(in, id, (char) (preds + portNum), p.name + "[" + j + "]", p.type.toString(Length.S), true); + currentEdges.add(e); + inputEdges.add(e); portNum++; } } } else { int in = readInt(); if (in >= 0) { - edges.add(new Edge(in, id, (char) (preds + portNum), p.name, p.type.toString(Length.S), true)); + Edge e = new Edge(in, id, (char) (preds + portNum), p.name, p.type.toString(Length.S), true); + currentEdges.add(e); + inputEdges.add(e); portNum++; } } @@ -761,19 +766,23 @@ for (int j = 0; j < size; j++) { int sux = readInt(); if (sux >= 0) { - edges.add(new Edge(id, sux, (char) portNum, p.name + "[" + j + "]", "Successor", false)); + Edge e = new Edge(id, sux, (char) portNum, p.name + "[" + j + "]", "Successor", false); + currentEdges.add(e); + succEdges.add(e); portNum++; } } } else { int sux = readInt(); if (sux >= 0) { - edges.add(new Edge(id, sux, (char) portNum, p.name, "Successor", false)); + Edge e = new Edge(id, sux, (char) portNum, p.name, "Successor", false); + currentEdges.add(e); + succEdges.add(e); portNum++; } } } - properties.setProperty("name", createName(edges.subList(edgesStart, edges.size()), props, nodeClass.nameTemplate)); + properties.setProperty("name", createName(currentEdges, props, nodeClass.nameTemplate)); properties.setProperty("class", nodeClass.className); switch (nodeClass.className) { case "BeginNode": @@ -786,9 +795,20 @@ graph.addNode(node); props.clear(); } - for (Edge e : edges) { - char fromIndex = e.input ? 1 : e.num; - char toIndex = e.input ? e.num : 0; + + Set nodesWithSuccessor = new HashSet<>(); + + for (Edge e : succEdges) { + assert !e.input; + char fromIndex = e.num; + nodesWithSuccessor.add(graph.getNode(e.from)); + char toIndex = 0; + graph.addEdge(InputEdge.createImmutable(fromIndex, toIndex, e.from, e.to, e.label, e.type)); + } + for (Edge e : inputEdges) { + assert e.input; + char fromIndex = (char) (nodesWithSuccessor.contains(graph.getNode(e.from)) ? 1 : 0); + char toIndex = e.num; graph.addEdge(InputEdge.createImmutable(fromIndex, toIndex, e.from, e.to, e.label, e.type)); } } diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java Sat Mar 21 15:41:38 2015 +0100 @@ -75,6 +75,7 @@ public static final String NODE_ID_PROPERTY = "id"; public static final String FROM_PROPERTY = "from"; public static final String TO_PROPERTY = "to"; + public static final String TYPE_PROPERTY = "type"; public static final String PROPERTY_NAME_PROPERTY = "name"; public static final String GRAPH_NAME_PROPERTY = "name"; public static final String FROM_INDEX_PROPERTY = "fromIndex"; @@ -387,6 +388,7 @@ int from = -1; int to = -1; String label = null; + String type = null; try { String fromIndexString = readAttribute(FROM_INDEX_PROPERTY); @@ -403,6 +405,7 @@ } label = readAttribute(LABEL_PROPERTY); + type = readAttribute(TYPE_PROPERTY); from = lookupID(readRequiredAttribute(FROM_PROPERTY)); to = lookupID(readRequiredAttribute(TO_PROPERTY)); @@ -410,7 +413,7 @@ throw new SAXException(e); } - InputEdge conn = new InputEdge((char) fromIndex, (char) toIndex, from, to, label, ""); + InputEdge conn = new InputEdge((char) fromIndex, (char) toIndex, from, to, label, type == null ? "" : type); return start(conn); } diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java Sat Mar 21 15:41:38 2015 +0100 @@ -240,6 +240,7 @@ } p.setProperty(Parser.TO_PROPERTY, Integer.toString(edge.getTo())); p.setProperty(Parser.FROM_PROPERTY, Integer.toString(edge.getFrom())); + p.setProperty(Parser.TYPE_PROPERTY, edge.getType()); return p; } } diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/graphdocument.xsd --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/graphdocument.xsd Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/graphdocument.xsd Sat Mar 21 15:41:38 2015 +0100 @@ -109,6 +109,7 @@ + diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalEdgeColorFilter.java --- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalEdgeColorFilter.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalEdgeColorFilter.java Sat Mar 21 15:41:38 2015 +0100 @@ -33,7 +33,6 @@ import java.awt.Color; import java.util.HashMap; import java.util.List; -import java.util.regex.Pattern; /** * Filter that colors usage and successor edges differently. @@ -42,7 +41,7 @@ */ public class GraalEdgeColorFilter extends AbstractFilter { - private HashMap usageColor = new HashMap<>(); + private final HashMap usageColor = new HashMap<>(); private Color otherUsageColor = Color.BLACK; public GraalEdgeColorFilter() { diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/beginend.filter --- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/beginend.filter Fri Mar 20 18:33:31 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -var f = new CombineFilter("Combine Filter"); -f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("class", ".*"), new Properties.RegexpPropertyMatcher("class", "BeginNode"), false, "shortName")); -f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("class", "EndNode"), new Properties.RegexpPropertyMatcher("class", ".*"), true, "shortName")); -f.apply(graph); diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/framestatelocks.filter --- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/framestatelocks.filter Fri Mar 20 18:33:31 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -colorize("class", "FrameState", red); -colorize("locks", "", gray); \ No newline at end of file diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/reduceEdges.filter --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/reduceEdges.filter Sat Mar 21 15:41:38 2015 +0100 @@ -0,0 +1,3 @@ +split("class", "ConstantLocationNode"); +split("class", "ParameterNode"); +split("class", "ConstantNode"); diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/layer.xml --- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/layer.xml Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/layer.xml Sat Mar 21 15:41:38 2015 +0100 @@ -18,7 +18,7 @@ - + @@ -26,10 +26,6 @@ - - - - diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java --- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java Sat Mar 21 15:41:38 2015 +0100 @@ -41,8 +41,9 @@ private InputGraph graph; private int curId; private String nodeText; - private Font font; - private Font slotFont; + private final Font font; + private final Font slotFont; + private final Font boldFont; public Font getFont() { return font; @@ -51,12 +52,17 @@ public Font getSlotFont() { return slotFont; } + + public Font getBoldFont() { + return boldFont; + } private Diagram() { figures = new ArrayList<>(); this.nodeText = ""; - this.font = new Font("Arial", Font.PLAIN, 13); + this.font = new Font("Arial", Font.PLAIN, 12); this.slotFont = new Font("Arial", Font.PLAIN, 10); + this.boldFont = this.font.deriveFont(Font.BOLD); } public String getNodeText() { diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java --- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java Sat Mar 21 15:41:38 2015 +0100 @@ -33,14 +33,10 @@ import java.util.List; import java.util.*; -/** - * - * @author Thomas Wuerthinger - */ public class Figure extends Properties.Entity implements Source.Provider, Vertex { - public static final int INSET = 12; - public static int SLOT_WIDTH = 12; + public static final int INSET = 8; + public static int SLOT_WIDTH = 10; public static final int OVERLAPPING = 6; public static final int SLOT_START = 4; public static final int SLOT_OFFSET = 8; diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java --- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java Sat Mar 21 15:41:38 2015 +0100 @@ -43,8 +43,8 @@ public static final int CROSSING_ITERATIONS = 2; public static final int DUMMY_HEIGHT = 1; public static final int DUMMY_WIDTH = 1; - public static final int X_OFFSET = 9; - public static final int LAYER_OFFSET = 30; + public static final int X_OFFSET = 8; + public static final int LAYER_OFFSET = 8; public static final int MAX_LAYER_LENGTH = -1; public static final int MIN_LAYER_DIFFERENCE = 1; public static final int VIP_BONUS = 10; @@ -75,8 +75,6 @@ private LayoutGraph graph; private List[] layers; private int layerCount; - private Set firstLayerHint; - private Set lastLayerHint; private Set importantLinks; private Set linksToFollow; @@ -181,17 +179,15 @@ @Override public void doLayout(LayoutGraph graph) { - doLayout(graph, new HashSet(), new HashSet(), new HashSet()); + doLayout(graph, new HashSet()); } @Override - public void doLayout(LayoutGraph graph, Set firstLayerHint, Set lastLayerHint, Set importantLinks) { + public void doLayout(LayoutGraph graph, Set importantLinks) { this.importantLinks = importantLinks; this.graph = graph; - this.firstLayerHint = firstLayerHint; - this.lastLayerHint = lastLayerHint; vertexToLayoutNode = new HashMap<>(); reversedLinks = new HashSet<>(); @@ -219,7 +215,6 @@ } for (LayoutEdge e : tmpArr) { - //System.out.println("Removed " + e); e.from.succs.remove(e); e.to.preds.remove(e); } @@ -302,8 +297,6 @@ Collections.reverse(points); - - if (cur.vertex == null && cur.preds.size() == 0) { if (reversedLinkEndPoints.containsKey(e.link)) { @@ -364,7 +357,7 @@ LayoutNode cur = e.to; LayoutNode other = e.from; LayoutEdge curEdge = e; - while (cur.vertex == null && cur.succs.size() != 0) { + while (cur.vertex == null && !cur.succs.isEmpty()) { if (points.size() > 1 && points.get(points.size() - 1).x == cur.x + cur.width / 2 && points.get(points.size() - 2).x == cur.x + cur.width / 2) { points.remove(points.size() - 1); } @@ -373,7 +366,7 @@ points.remove(points.size() - 1); } points.add(new Point(cur.x + cur.width / 2, cur.y + cur.height)); - if (cur.succs.size() == 0) { + if (cur.succs.isEmpty()) { break; } assert cur.succs.size() == 1; @@ -381,15 +374,13 @@ cur = curEdge.to; } - p = new Point(cur.x + curEdge.relativeTo, cur.y + cur.yOffset + ((curEdge.link == null) ? 0 : curEdge.link.getTo().getRelativePosition().y)); points.add(p); if (curEdge.to.inOffsets.containsKey(curEdge.relativeTo)) { points.add(new Point(p.x, p.y + curEdge.to.inOffsets.get(curEdge.relativeTo) + ((curEdge.link == null) ? 0 : curEdge.link.getTo().getRelativePosition().y))); } - - if (cur.succs.size() == 0 && cur.vertex == null) { + if (cur.succs.isEmpty() && cur.vertex == null) { if (reversedLinkStartPoints.containsKey(e.link)) { for (Point p1 : reversedLinkStartPoints.get(e.link)) { points.add(0, new Point(p1.x + other.x, p1.y + other.y)); @@ -528,13 +519,34 @@ private static final Comparator nodeProcessingDownComparator = new Comparator() { @Override public int compare(LayoutNode n1, LayoutNode n2) { + int n1VIP = 0; + for (LayoutEdge e : n1.preds) { + if (e.vip) { + n1VIP++; + } + } + int n2VIP = 0; + for (LayoutEdge e : n1.preds) { + if (e.vip) { + n2VIP++; + } + } + if (n1VIP != n2VIP) { + return n2VIP - n1VIP; + } if (n1.vertex == null) { if (n2.vertex == null) { return 0; } + if (n1.preds.size() == 1 && n1.preds.get(0).from.vertex != null) { + return 1; + } return -1; } if (n2.vertex == null) { + if (n2.preds.size() == 1 && n2.preds.get(0).from.vertex != null) { + return -1; + } return 1; } return n1.preds.size() - n2.preds.size(); @@ -544,15 +556,36 @@ @Override public int compare(LayoutNode n1, LayoutNode n2) { + int n1VIP = 0; + for (LayoutEdge e : n1.succs) { + if (e.vip) { + n1VIP++; + } + } + int n2VIP = 0; + for (LayoutEdge e : n1.succs) { + if (e.vip) { + n2VIP++; + } + } if (n1.vertex == null) { if (n2.vertex == null) { return 0; } + if (n1.succs.size() == 1 && n1.succs.get(0).to.vertex != null) { + return 1; + } return -1; } if (n2.vertex == null) { + if (n2.succs.size() == 1 && n2.succs.get(0).to.vertex != null) { + return -1; + } return 1; } + if (n1VIP != n2VIP) { + return n2VIP - n1VIP; + } return n1.succs.size() - n2.succs.size(); } }; @@ -568,7 +601,7 @@ n.x = space[n.layer].get(n.pos); } } - + @SuppressWarnings("unchecked") private void createArrays() { space = new ArrayList[layers.length]; @@ -600,13 +633,23 @@ initialPositions(); for (int i = 0; i < SWEEP_ITERATIONS; i++) { sweepDown(); + adjustSpace(); sweepUp(); + adjustSpace(); } - + sweepDown(); - //for (int i = 0; i < SWEEP_ITERATIONS; i++) { - // doubleSweep(); - //} + } + + private void adjustSpace() { + for (int i = 0; i < layers.length; i++) { + // space[i] = new ArrayList<>(); + int curX = 0; + for (LayoutNode n : layers[i]) { + space[i].add(n.x); +// curX += n.width + xOffset; + } + } } private int calculateOptimalDown(LayoutNode n) { @@ -629,7 +672,7 @@ if (n.preds.size() == n.succs.size()) { return n.x; } - + int[] values = new int[n.preds.size() + n.succs.size()]; int i = 0; @@ -747,7 +790,7 @@ n.x = pos; } - assert minX <= maxX; + assert minX <= maxX : minX + " vs " + maxX; } treeSet.add(n); @@ -769,7 +812,7 @@ assert n.layer < layerCount; } } - + @SuppressWarnings("unchecked") private void createLayers() { layers = new List[layerCount]; @@ -789,7 +832,7 @@ if (n.layer == 0) { layers[0].add(n); visited.add(n); - } else if (n.preds.size() == 0) { + } else if (n.preds.isEmpty()) { layers[n.layer].add(n); visited.add(n); } @@ -806,7 +849,6 @@ } } - updatePositions(); initX(); @@ -816,11 +858,7 @@ downSweep(); upSweep(); } - if (reversedLinks.isEmpty()) { - // This graph seems to be a tree or forest. - // A final down-sweep will usually give us a better layout. - downSweep(); - } + downSweep(); } private void initX() { @@ -869,8 +907,8 @@ if (e.vip) { factor = VIP_BONUS; } - sum += cur*factor; - count+=factor; + sum += cur * factor; + count += factor; } if (count > 0) { @@ -879,7 +917,6 @@ } } - updateCrossingNumbers(i, true); Collections.sort(layers[i], crossingNodeComparator); updateXOfLayer(i); @@ -940,8 +977,8 @@ if (e.vip) { factor = VIP_BONUS; } - sum += cur*factor; - count+=factor; + sum += cur * factor; + count += factor; } if (count > 0) { @@ -1012,7 +1049,7 @@ } curY += maxHeight + baseLine + bottomBaseLine; - curY += layerOffset + (int) Math.sqrt(maxXOffset); + curY += layerOffset + ((int) (Math.sqrt(maxXOffset) * 1.5)); } } } @@ -1041,7 +1078,6 @@ protected void run() { oldNodeCount = nodes.size(); - if (combine == Combine.SAME_OUTPUTS) { Comparator comparator = new Comparator() { @@ -1154,7 +1190,6 @@ maxLayer = Math.max(maxLayer, curEdge.to.layer); } - int cnt = maxLayer - n.layer - 1; LayoutEdge[] edges = new LayoutEdge[cnt]; LayoutNode[] nodes = new LayoutNode[cnt]; @@ -1279,91 +1314,109 @@ @Override protected void run() { - - List insertOrder = new ArrayList<>(); + assignLayerDownwards(); + assignLayerUpwards(); + } - HashSet set = new HashSet<>(); + private void assignLayerDownwards() { + ArrayList hull = new ArrayList<>(); for (LayoutNode n : nodes) { - if (n.preds.size() == 0) { - set.add(n); - insertOrder.add(n); + if (n.preds.isEmpty()) { + hull.add(n); n.layer = 0; } } int z = minLayerDifference; - HashSet newSet = new HashSet<>(); - HashSet failed = new HashSet<>(); - while (!set.isEmpty()) { - - newSet.clear(); - failed.clear(); - - for (LayoutNode n : set) { - + while (!hull.isEmpty()) { + ArrayList newSet = new ArrayList<>(); + for (LayoutNode n : hull) { for (LayoutEdge se : n.succs) { LayoutNode s = se.to; - if (!newSet.contains(s) && !failed.contains(s)) { - boolean ok = true; + if (s.layer != -1) { + // This node was assigned before. + } else { + boolean unassignedPred = false; for (LayoutEdge pe : s.preds) { LayoutNode p = pe.from; - if (p.layer == -1) { - ok = false; + if (p.layer == -1 || p.layer >= z) { + // This now has an unscheduled successor or a successor that was scheduled only in this round. + unassignedPred = true; break; } } - if (ok) { + if (unassignedPred) { + // This successor node can not yet be assigned. + } else { + s.layer = z; newSet.add(s); - } else { - failed.add(s); } } } - } - for (LayoutNode n : newSet) { - n.layer = z; - insertOrder.add(n); - } - - // Swap sets - HashSet tmp = set; - set = newSet; - newSet = tmp; + hull = newSet; z += minLayerDifference; } - optimize(insertOrder); + layerCount = z - minLayerDifference; + for (LayoutNode n : nodes) { + n.layer = (layerCount - 1 - n.layer); + } + } + + private void assignLayerUpwards() { + ArrayList hull = new ArrayList<>(); + for (LayoutNode n : nodes) { + if (n.succs.isEmpty()) { + hull.add(n); + } else { + n.layer = -1; + } + } + + int z = minLayerDifference; + while (!hull.isEmpty()) { + ArrayList newSet = new ArrayList<>(); + for (LayoutNode n : hull) { + if (n.layer < z) { + for (LayoutEdge se : n.preds) { + LayoutNode s = se.from; + if (s.layer != -1) { + // This node was assigned before. + } else { + boolean unassignedSucc = false; + for (LayoutEdge pe : s.succs) { + LayoutNode p = pe.to; + if (p.layer == -1 || p.layer >= z) { + // This now has an unscheduled successor or a successor that was scheduled only in this round. + unassignedSucc = true; + break; + } + } + + if (unassignedSucc) { + // This predecessor node can not yet be assigned. + } else { + s.layer = z; + newSet.add(s); + } + } + } + } else { + newSet.add(n); + } + } + + hull = newSet; + z += minLayerDifference; + } layerCount = z - minLayerDifference; - for (Vertex v : lastLayerHint) { - - LayoutNode n = vertexToLayoutNode.get(v); - assert n.succs.size() == 0; - n.layer = layerCount - 1; - } - - for (Vertex v : firstLayerHint) { - LayoutNode n = vertexToLayoutNode.get(v); - assert n.preds.size() == 0; - n.layer = 0; - assert n.layer == 0; - } - } - - public void optimize(List insertOrder) { - for (int i = insertOrder.size() - 1; i >= 0; i--) { - LayoutNode cur = insertOrder.get(i); - if (cur.succs.size() > cur.preds.size()) { - int minLayer = cur.succs.get(0).to.layer; - for (LayoutEdge e : cur.succs) { - minLayer = Math.min(minLayer, e.to.layer); - } - cur.layer = minLayer - 1; - } + for (LayoutNode n : nodes) { + n.layer = (layerCount - 1 - n.layer); } } @@ -1415,7 +1468,6 @@ } } - // Start DFS and reverse back edges visited = new HashSet<>(); active = new HashSet<>(); @@ -1423,7 +1475,6 @@ DFS(node); } - for (LayoutNode node : nodes) { SortedSet reversedDown = new TreeSet<>(); @@ -1434,7 +1485,6 @@ } } - SortedSet reversedUp = null; if (reversedDown.size() == 0) { reversedUp = new TreeSet<>(Collections.reverseOrder()); @@ -1522,7 +1572,6 @@ curX += offset; node.bottomYOffset += offset; - endPoints.add(new Point(pos, node.height)); endPoints.add(new Point(pos, oldNodeHeight)); for (LayoutEdge e : reversedPreds) { @@ -1530,7 +1579,6 @@ } } - if (minX < 0) { for (LayoutEdge e : node.preds) { e.relativeTo -= minX; @@ -1701,12 +1749,12 @@ edge.from.succs.add(edge); edge.to.preds.add(edge); edge.vip = l.isVIP(); - //assert edge.from != edge.to; // No self-loops allowed + //assert edge.from != edge.to; // No self-loops allowed } for (Link l : importantLinks) { - if (!vertexToLayoutNode.containsKey(l.getFrom().getVertex()) || - vertexToLayoutNode.containsKey(l.getTo().getVertex())) { + if (!vertexToLayoutNode.containsKey(l.getFrom().getVertex()) + || vertexToLayoutNode.containsKey(l.getTo().getVertex())) { continue; } LayoutNode from = vertexToLayoutNode.get(l.getFrom().getVertex()); diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutManager.java --- a/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutManager.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutManager.java Sat Mar 21 15:41:38 2015 +0100 @@ -33,7 +33,7 @@ public void doLayout(LayoutGraph graph); - public void doLayout(LayoutGraph graph, Set firstLayerHint, Set lastLayerHint, Set importantLinks); + public void doLayout(LayoutGraph graph, Set importantLinks); public void doRouting(LayoutGraph graph); } diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ColorIcon.java --- a/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ColorIcon.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ColorIcon.java Sat Mar 21 15:41:38 2015 +0100 @@ -34,7 +34,7 @@ */ public class ColorIcon implements Icon { - private Color color; + private final Color color; public ColorIcon(Color c) { color = c; @@ -42,8 +42,10 @@ @Override public void paintIcon(Component c, Graphics g, int x, int y) { + Color oldColor = g.getColor(); g.setColor(color); g.fillRect(x, y, 16, 16); + g.setColor(oldColor); } @Override diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java --- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java Sat Mar 21 15:41:38 2015 +0100 @@ -71,6 +71,7 @@ private Lookup lookup; private InstanceContent content; private Action[] actions; + private Action[] actionsWithSelection; private LayerWidget connectionLayer; private JScrollPane scrollPane; private UndoRedo.Manager undoRedoManager; @@ -100,7 +101,7 @@ public static final float ZOOM_MAX_FACTOR = 3.0f; public static final float ZOOM_MIN_FACTOR = 0.0f;//0.15f; public static final float ZOOM_INCREMENT = 1.5f; - public static final int SLOT_OFFSET = 6; + public static final int SLOT_OFFSET = 8; public static final int ANIMATION_LIMIT = 40; private PopupMenuProvider popupMenuProvider = new PopupMenuProvider() { @@ -374,9 +375,10 @@ } }; - public DiagramScene(Action[] actions, DiagramViewModel model) { + public DiagramScene(Action[] actions, Action[] actionsWithSelection, DiagramViewModel model) { this.actions = actions; + this.actionsWithSelection = actionsWithSelection; content = new InstanceContent(); lookup = new AbstractLookup(content); @@ -399,6 +401,9 @@ blockLayer = new LayerWidget(this); this.addChild(blockLayer); + connectionLayer = new LayerWidget(this); + this.addChild(connectionLayer); + mainLayer = new LayerWidget(this); this.addChild(mainLayer); @@ -410,9 +415,6 @@ bottomRight.setPreferredLocation(new Point(-BORDER_SIZE, -BORDER_SIZE)); this.addChild(bottomRight); - connectionLayer = new LayerWidget(this); - this.addChild(connectionLayer); - LayerWidget selectionLayer = new LayerWidget(this); this.addChild(selectionLayer); @@ -451,12 +453,21 @@ } public boolean isAllVisible() { - return getModel().getHiddenNodes().size() == 0; + return getModel().getHiddenNodes().isEmpty(); } public Action createGotoAction(final Figure f) { final DiagramScene diagramScene = this; - Action a = new AbstractAction() { + String name = f.getLines()[0]; + + name += " ("; + + final boolean hidden = !this.getWidget(f, FigureWidget.class).isVisible(); + if (hidden) { + name += "hidden"; + } + name += ")"; + Action a = new AbstractAction(name, new ColorIcon(f.getColor())) { @Override public void actionPerformed(ActionEvent e) { @@ -465,16 +476,6 @@ }; a.setEnabled(true); - a.putValue(Action.SMALL_ICON, new ColorIcon(f.getColor())); - String name = f.getLines()[0]; - - name += " ("; - - if (!this.getWidget(f, FigureWidget.class).isVisible()) { - name += "hidden"; - } - name += ")"; - a.putValue(Action.NAME, name); return a; } @@ -538,8 +539,6 @@ } private void smallUpdate(boolean relayout) { - - System.out.println("smallUpdate " + relayout); this.updateHiddenNodes(model.getHiddenNodes(), relayout); boolean b = this.getUndoRedoEnabled(); this.setUndoRedoEnabled(false); @@ -559,8 +558,6 @@ } private void relayout(Set oldVisibleWidgets) { - System.out.println("relayout called with old visible widgets: " + oldVisibleWidgets); - Diagram diagram = getModel().getDiagramToView(); HashSet
figures = new HashSet<>(); @@ -589,8 +586,6 @@ private void relayoutWithoutLayout(Set oldVisibleWidgets) { - System.out.println("relayout without layout with visible widgets: " + oldVisibleWidgets); - Diagram diagram = getModel().getDiagramToView(); int maxX = -BORDER_SIZE; @@ -958,8 +953,6 @@ private void updateHiddenNodes(Set newHiddenNodes, boolean doRelayout) { - System.out.println("newHiddenNodes: " + newHiddenNodes); - Diagram diagram = getModel().getDiagramToView(); assert diagram != null; @@ -1027,7 +1020,7 @@ private void showFigure(Figure f) { HashSet newHiddenNodes = new HashSet<>(getModel().getHiddenNodes()); newHiddenNodes.removeAll(f.getSource().getSourceNodesAsSet()); - updateHiddenNodes(newHiddenNodes, true); + this.model.setHiddenNodes(newHiddenNodes); } public void show(final Figure f) { @@ -1062,7 +1055,12 @@ public JPopupMenu createPopupMenu() { JPopupMenu menu = new JPopupMenu(); - for (Action a : actions) { + + Action[] currentActions = actionsWithSelection; + if (this.getSelectedObjects().isEmpty()) { + currentActions = actions; + } + for (Action a : currentActions) { if (a == null) { menu.addSeparator(); } else { diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java --- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java Sat Mar 21 15:41:38 2015 +0100 @@ -246,7 +246,7 @@ if (last == null) { curColor = Color.green; } else { - if (last.equals(cur)) { + if (last.equals(cur) && last.getProperties().equals(cur.getProperties())) { if (curColor == Color.black) { curColor = Color.white; } @@ -268,7 +268,6 @@ } public void showNot(final Set nodes) { - System.out.println("Shownot called with " + nodes); setHiddenNodes(nodes); } diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java --- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java Sat Mar 21 15:41:38 2015 +0100 @@ -178,12 +178,17 @@ null, ZoomInAction.get(ZoomInAction.class), ZoomOutAction.get(ZoomOutAction.class), + }; + + + Action[] actionsWithSelection = new Action[]{ + ExtractAction.get(ExtractAction.class), + ShowAllAction.get(HideAction.class), null, ExpandPredecessorsAction.get(ExpandPredecessorsAction.class), ExpandSuccessorsAction.get(ExpandSuccessorsAction.class) }; - initComponents(); ToolbarPool.getDefault().setPreferredIconSize(16); @@ -201,7 +206,7 @@ JScrollPane pane = new JScrollPane(rangeSlider, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); container.add(BorderLayout.CENTER, pane); - scene = new DiagramScene(actions, rangeSliderModel); + scene = new DiagramScene(actions, actionsWithSelection, rangeSliderModel); content = new InstanceContent(); graphContent = new InstanceContent(); this.associateLookup(new ProxyLookup(new Lookup[]{scene.getLookup(), new AbstractLookup(graphContent), new AbstractLookup(content)})); diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/FigureWidget.java --- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/FigureWidget.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/FigureWidget.java Sat Mar 21 15:41:38 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,11 +62,7 @@ public class FigureWidget extends Widget implements Properties.Provider, PopupMenuProvider, DoubleClickHandler { public static final boolean VERTICAL_LAYOUT = true; - //public static final int MAX_STRING_LENGTH = 20; private static final double LABEL_ZOOM_FACTOR = 0.3; - private static final double ZOOM_FACTOR = 0.1; - private Font font; - private Font boldFont; private Figure figure; private Widget leftWidget; private Widget rightWidget; @@ -74,7 +70,7 @@ private ArrayList labelWidgets; private DiagramScene diagramScene; private boolean boundary; - private Node node; + private final Node node; private Widget dummyTop; public void setBoundary(boolean b) { @@ -89,11 +85,10 @@ return node; } - @Override - public boolean isHitAt(Point localLocation) { - return middleWidget.isHitAt(localLocation); - } - + @Override + public boolean isHitAt(Point localLocation) { + return middleWidget.isHitAt(localLocation); + } public FigureWidget(final Figure f, WidgetAction hoverAction, WidgetAction selectAction, DiagramScene scene, Widget parent) { @@ -103,23 +98,20 @@ assert this.getScene().getView() != null; this.figure = f; - font = f.getDiagram().getFont(); - boldFont = f.getDiagram().getFont().deriveFont(Font.BOLD); this.setCheckClipping(true); this.diagramScene = scene; parent.addChild(this); - Widget outer = new Widget(scene); - outer.setBackground(f.getColor()); - outer.setLayout(LayoutFactory.createOverlayLayout()); - + Widget outer = new Widget(scene); + outer.setBackground(f.getColor()); + outer.setLayout(LayoutFactory.createOverlayLayout()); + middleWidget = new Widget(scene); middleWidget.setLayout(LayoutFactory.createVerticalFlowLayout(LayoutFactory.SerialAlignment.CENTER, 0)); middleWidget.setBackground(f.getColor()); middleWidget.setOpaque(true); - //middleWidget.setBorder(BorderFactory.createLineBorder(Color.BLACK)); middleWidget.getActions().addAction(new DoubleClickAction(this)); - middleWidget.setCheckClipping(true); + middleWidget.setCheckClipping(true); labelWidgets = new ArrayList<>(); @@ -129,7 +121,6 @@ dummyTop.setMinimumSize(new Dimension(Figure.INSET / 2, 1)); middleWidget.addChild(dummyTop); - for (String cur : strings) { String displayString = cur; @@ -138,11 +129,11 @@ labelWidgets.add(lw); middleWidget.addChild(lw); lw.setLabel(displayString); - lw.setFont(font); + lw.setFont(figure.getDiagram().getFont()); lw.setForeground(Color.BLACK); lw.setAlignment(LabelWidget.Alignment.CENTER); lw.setVerticalAlignment(LabelWidget.VerticalAlignment.CENTER); - lw.setBorder(BorderFactory.createEmptyBorder()); + lw.setBorder(BorderFactory.createEmptyBorder()); } Widget dummyBottom = new Widget(scene); @@ -150,7 +141,6 @@ middleWidget.addChild(dummyBottom); middleWidget.setPreferredBounds(new Rectangle(0, Figure.SLOT_WIDTH - Figure.OVERLAPPING, f.getWidth(), f.getHeight())); - //outer.addChild(middleWidget); this.addChild(middleWidget); // Initialize node for property sheet @@ -178,49 +168,22 @@ protected void notifyStateChanged(ObjectState previousState, ObjectState state) { super.notifyStateChanged(previousState, state); - Color borderColor = Color.BLACK; - Color innerBorderColor = getFigure().getColor(); - int thickness = 1; - boolean repaint = false; - Font f = font; - if (state.isSelected() || state.isHighlighted()) { - thickness = 2; - } - if(state.isSelected()) { - f = boldFont; - innerBorderColor = borderColor; - } else { - } - - if (state.isHighlighted()) { - innerBorderColor = borderColor = Color.BLUE; - repaint = true; - } else { - repaint = true; - } - - if (state.isHovered() != previousState.isHovered()) { - - /* - if (state.isHovered()) { - diagramScene.addAllHighlighted(this.getFigure().getSource().getSourceNodesAsSet()); - } else { - diagramScene.removeAllHighlighted(this.getFigure().getSource().getSourceNodesAsSet()); - }*/ - repaint = true; + Font font = this.figure.getDiagram().getFont(); + if (state.isSelected()) { + font = this.figure.getDiagram().getBoldFont(); } - if (state.isSelected() != previousState.isSelected()) { - repaint = true; + Color borderColor = Color.BLACK; + Color innerBorderColor = getFigure().getColor(); + if (state.isHighlighted()) { + innerBorderColor = borderColor = Color.BLUE; } - if (repaint) { - middleWidget.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(borderColor, 1), BorderFactory.createLineBorder(innerBorderColor, 1))); - for (LabelWidget labelWidget : labelWidgets) { - labelWidget.setFont(f); - } - repaint(); + middleWidget.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(borderColor, 1), BorderFactory.createLineBorder(innerBorderColor, 1))); + for (LabelWidget labelWidget : labelWidgets) { + labelWidget.setFont(font); } + repaint(); } public String getName() { @@ -246,7 +209,6 @@ } if (diagramScene.getZoomFactor() < LABEL_ZOOM_FACTOR) { - for (LabelWidget labelWidget : labelWidgets) { labelWidget.setVisible(false); } @@ -263,19 +225,15 @@ getScene().getGraphics().setComposite(oldComposite); } } - + @Override public JPopupMenu getPopupMenu(Widget widget, Point point) { JPopupMenu menu = diagramScene.createPopupMenu(); menu.addSeparator(); - - JMenu predecessors = new JMenu("Nodes Above"); - predecessors.addMenuListener(new NeighborMenuListener(predecessors, getFigure(), false)); - menu.add(predecessors); - - JMenu successors = new JMenu("Nodes Below"); - successors.addMenuListener(new NeighborMenuListener(successors, getFigure(), true)); - menu.add(successors); + + build(menu, getFigure(), this, false, diagramScene); + menu.addSeparator(); + build(menu, getFigure(), this, true, diagramScene); if (getFigure().getSubgraphs() != null) { menu.addSeparator(); @@ -283,7 +241,7 @@ menu.add(subgraphs); final GraphViewer viewer = Lookup.getDefault().lookup(GraphViewer.class); - for(final InputGraph subgraph : getFigure().getSubgraphs()) { + for (final InputGraph subgraph : getFigure().getSubgraphs()) { Action a = new AbstractAction() { @Override @@ -301,10 +259,45 @@ return menu; } + public static void build(JPopupMenu menu, Figure figure, FigureWidget figureWidget, boolean successors, DiagramScene diagramScene) { + Set
set = figure.getPredecessorSet(); + if (successors) { + set = figure.getSuccessorSet(); + } + + boolean first = true; + for (Figure f : set) { + if (f == figure) { + continue; + } + + if (first) { + first = false; + } else { + menu.addSeparator(); + } + + Action go = diagramScene.createGotoAction(f); + menu.add(go); + + JMenu preds = new JMenu("Nodes Above"); + preds.addMenuListener(figureWidget.new NeighborMenuListener(preds, f, false)); + menu.add(preds); + + JMenu succs = new JMenu("Nodes Below"); + succs.addMenuListener(figureWidget.new NeighborMenuListener(succs, f, true)); + menu.add(succs); + } + + if (figure.getPredecessorSet().isEmpty() && figure.getSuccessorSet().isEmpty()) { + menu.add("(none)"); + } + } + /** * Builds the submenu for a figure's neighbors on demand. */ - private class NeighborMenuListener implements MenuListener { + public class NeighborMenuListener implements MenuListener { private final JMenu menu; private final Figure figure; @@ -323,38 +316,7 @@ return; } - Set
set = figure.getPredecessorSet(); - if (successors) { - set = figure.getSuccessorSet(); - } - - boolean first = true; - for (Figure f : set) { - if (f == figure) { - continue; - } - - if (first) { - first = false; - } else { - menu.addSeparator(); - } - - Action go = diagramScene.createGotoAction(f); - menu.add(go); - - JMenu preds = new JMenu("Nodes Above"); - preds.addMenuListener(new NeighborMenuListener(preds, f, false)); - menu.add(preds); - - JMenu succs = new JMenu("Nodes Below"); - succs.addMenuListener(new NeighborMenuListener(succs, f, true)); - menu.add(succs); - } - - if (menu.getItemCount() == 0) { - menu.add("(none)"); - } + build(menu.getPopupMenu(), figure, FigureWidget.this, successors, diagramScene); } @Override diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java --- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java Sat Mar 21 15:41:38 2015 +0100 @@ -109,7 +109,6 @@ if (connections.size() > 0) { color = connections.get(0).getColor(); } - this.setToolTipText("" + generateToolTipText(this.connections) + ""); this.setCheckClipping(true); @@ -203,7 +202,7 @@ g.drawLine(from.x, from.y, to.x, to.y); boolean sameFrom = false; - boolean sameTo = successors.size() == 0; + boolean sameTo = successors.isEmpty(); for (LineWidget w : successors) { if (w.getFrom().equals(getTo())) { sameTo = true; diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/OutputSlotWidget.java --- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/OutputSlotWidget.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/OutputSlotWidget.java Sat Mar 21 15:41:38 2015 +0100 @@ -41,12 +41,9 @@ public OutputSlotWidget(OutputSlot slot, DiagramScene scene, Widget parent, FigureWidget fw) { super(slot, scene, parent, fw); outputSlot = slot; - //init(); - //getFigureWidget().getRightWidget().addChild(this); Point p = outputSlot.getRelativePosition(); p.y += getSlot().getFigure().getHeight() - Figure.SLOT_START; p.x -= this.calculateClientArea().width / 2; - //p.x += this.calculateClientArea().width / 2; this.setPreferredLocation(p); } @@ -56,21 +53,9 @@ @Override protected int calculateSlotWidth() { - List slots = getSlot().getFigure().getOutputSlots(); assert slots.contains(getSlot()); return calculateWidth(slots.size()); } - /* - protected Point calculateRelativeLocation() { - if (getFigureWidget().getBounds() == null) { - return new Point(0, 0); - } - - double x = this.getFigureWidget().getBounds().width; - List slots = outputSlot.getFigure().getOutputSlots(); - assert slots.contains(outputSlot); - return new Point((int) x, (int) (calculateRelativeY(slots.size(), slots.indexOf(outputSlot)))); - }*/ } diff -r b5516d27d657 -r 3c78119de0cd src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/SlotWidget.java --- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/SlotWidget.java Fri Mar 20 18:33:31 2015 +0100 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/SlotWidget.java Sat Mar 21 15:41:38 2015 +0100 @@ -59,17 +59,16 @@ this.setToolTipText("" + slot.getToolTipText() + ""); this.setCheckClipping(true); parent.addChild(this); - + //this.setPreferredBounds(this.calculateClientArea()); } - - + @Override protected void notifyStateChanged(ObjectState previousState, ObjectState state) { super.notifyStateChanged(previousState, state); - repaint(); + repaint(); } - + public Slot getSlot() { return slot; } @@ -86,58 +85,59 @@ } Graphics2D g = this.getGraphics(); - // g.setColor(Color.DARK_GRAY); + // g.setColor(Color.DARK_GRAY); int w = this.getBounds().width; int h = this.getBounds().height; - if(getSlot().getSource().getSourceNodes().size() > 0) { + if (getSlot().getSource().getSourceNodes().size() > 0) { final int SMALLER = 0; g.setColor(getSlot().getColor()); int FONT_OFFSET = 2; - + int s = h - SMALLER; int rectW = s; - + Font font = this.getSlot().getFigure().getDiagram().getSlotFont(); - if(this.getState().isSelected()) { + if (this.getState().isSelected()) { font = font.deriveFont(Font.BOLD); } - + if (getSlot().getShortName() != null && getSlot().getShortName().length() > 0) { g.setFont(font); Rectangle2D r1 = g.getFontMetrics().getStringBounds(getSlot().getShortName(), g); - rectW = (int)r1.getWidth() + FONT_OFFSET * 2; + rectW = (int) r1.getWidth() + FONT_OFFSET * 2; } - g.fillRect(w/2 - rectW/2, 0, rectW-1, s-1); - - if(this.getState().isHighlighted()) { + g.fillRect(w / 2 - rectW / 2, 0, rectW - 1, s - 1); + + if (this.getState().isHighlighted()) { g.setColor(Color.BLUE); } else { g.setColor(Color.BLACK); } - g.drawRect(w/2 - rectW/2, 0, rectW-1, s-1); - - + g.drawRect(w / 2 - rectW / 2, 0, rectW - 1, s - 1); + if (getSlot().getShortName() != null && getSlot().getShortName().length() > 0 && getScene().getZoomFactor() >= TEXT_ZOOM_FACTOR) { Rectangle2D r1 = g.getFontMetrics().getStringBounds(getSlot().getShortName(), g); - g.drawString(getSlot().getShortName(), (int) (w - r1.getWidth()) / 2, g.getFontMetrics().getAscent()-1);//(int) (r1.getHeight())); + g.drawString(getSlot().getShortName(), (int) (w - r1.getWidth()) / 2, g.getFontMetrics().getAscent() - 1);//(int) (r1.getHeight())); } - + } else { - if(this.getState().isHighlighted()) { - g.setColor(Color.BLUE); + if (this.getSlot().getConnections().isEmpty()) { + if (this.getState().isHighlighted()) { + g.setColor(Color.BLUE); + } else { + g.setColor(Color.BLACK); + } + int r = 2; + if (slot instanceof OutputSlot) { + g.fillOval(w / 2 - r, Figure.SLOT_WIDTH - Figure.SLOT_START - r, 2 * r, 2 * r); + } else { + g.fillOval(w / 2 - r, Figure.SLOT_START - r, 2 * r, 2 * r); + } } else { - g.setColor(Color.BLACK); - } - int r = 2; - if (slot instanceof OutputSlot) { - g.fillOval(w/2-r, Figure.SLOT_WIDTH - Figure.SLOT_START - r, 2*r, 2*r); - //g.fillArc(w / 2 - r, -r, 2*r, 2*r, 180, 180); - } else { - g.fillOval(w/2-r, Figure.SLOT_START - r, 2*r, 2*r); - //g.fillArc(w / 2 - r, h - r, 2*r, 2*r, 0, 180); + // Do not paint a slot without connections. } } } @@ -146,9 +146,9 @@ protected Rectangle calculateClientArea() { return new Rectangle(0, 0, slot.getWidth(), Figure.SLOT_WIDTH); } - + protected abstract int calculateSlotWidth(); - + protected int calculateWidth(int count) { return getFigureWidget().getFigure().getWidth() / count; } @@ -158,19 +158,19 @@ Set hiddenNodes = new HashSet<>(diagramScene.getModel().getHiddenNodes()); if (diagramScene.isAllVisible()) { hiddenNodes = new HashSet<>(diagramScene.getModel().getGraphToView().getGroup().getAllNodes()); - } + } boolean progress = false; - for(Figure f : diagramScene.getModel().getDiagramToView().getFigures()) { - for(Slot s : f.getSlots()) { - if(DiagramScene.doesIntersect(s.getSource().getSourceNodesAsSet(), slot.getSource().getSourceNodesAsSet())) { + for (Figure f : diagramScene.getModel().getDiagramToView().getFigures()) { + for (Slot s : f.getSlots()) { + if (DiagramScene.doesIntersect(s.getSource().getSourceNodesAsSet(), slot.getSource().getSourceNodesAsSet())) { progress = true; hiddenNodes.removeAll(f.getSource().getSourceNodesAsSet()); } } } - if(progress) { + if (progress) { this.diagramScene.getModel().showNot(hiddenNodes); } }