8345039: IGV: save user-defined node colors to XML

Co-authored-by: Roberto Castañeda Lozano <rcastanedalo@openjdk.org>
Co-authored-by: Christian Hagedorn <chagedorn@openjdk.org>
Reviewed-by: chagedorn, epeter, rcastanedalo
This commit is contained in:
Tobias Holenstein 2024-11-29 15:21:39 +00:00
parent 28b0f3eaa5
commit a80ccf2cd2
6 changed files with 75 additions and 6 deletions

View file

@ -23,6 +23,7 @@
*/ */
package com.sun.hotspot.igv.data; package com.sun.hotspot.igv.data;
import java.awt.Color;
import java.util.Objects; import java.util.Objects;
/** /**
@ -67,4 +68,27 @@ public class InputNode extends Properties.Entity {
public String toString() { public String toString() {
return "Node " + id + " " + getProperties().toString(); return "Node " + id + " " + getProperties().toString();
} }
public void setCustomColor(Color color) {
if (color != null) {
String hexColor = String.format("#%08X", color.getRGB());
getProperties().setProperty("color", hexColor);
} else {
getProperties().setProperty("color", null);
}
}
public Color getCustomColor() {
String hexColor = getProperties().get("color");
if (hexColor != null) {
try {
String hex = hexColor.startsWith("#") ? hexColor.substring(1) : hexColor;
int argb = (int) Long.parseLong(hex, 16);
return new Color(argb, true);
} catch (Exception ignored) {
return null;
}
}
return null;
}
} }

View file

@ -36,6 +36,7 @@ public class Diagram {
private final Map<InputNode, Figure> figures; private final Map<InputNode, Figure> figures;
private final Map<InputBlock, Block> blocks; private final Map<InputBlock, Block> blocks;
private final InputGraph inputGraph;
private final String nodeText; private final String nodeText;
private final String shortNodeText; private final String shortNodeText;
private final String tinyNodeText; private final String tinyNodeText;
@ -66,6 +67,7 @@ public class Diagram {
this.figures = new LinkedHashMap<>(); this.figures = new LinkedHashMap<>();
this.blocks = new LinkedHashMap<>(8); this.blocks = new LinkedHashMap<>(8);
this.blockConnections = new HashSet<>(); this.blockConnections = new HashSet<>();
this.inputGraph = graph;
this.cfg = false; this.cfg = false;
int curId = 0; int curId = 0;
@ -128,6 +130,10 @@ public class Diagram {
} }
} }
public InputGraph getInputGraph() {
return inputGraph;
}
public Block getBlock(InputBlock b) { public Block getBlock(InputBlock b) {
assert blocks.containsKey(b); assert blocks.containsKey(b);
return blocks.get(b); return blocks.get(b);

View file

@ -23,6 +23,7 @@
*/ */
package com.sun.hotspot.igv.graph; package com.sun.hotspot.igv.graph;
import com.sun.hotspot.igv.data.InputGraph;
import com.sun.hotspot.igv.data.InputNode; import com.sun.hotspot.igv.data.InputNode;
import com.sun.hotspot.igv.data.Properties; import com.sun.hotspot.igv.data.Properties;
import com.sun.hotspot.igv.layout.Cluster; import com.sun.hotspot.igv.layout.Cluster;
@ -153,8 +154,13 @@ public class Figure extends Properties.Entity implements Vertex {
} }
public Color getColor() { public Color getColor() {
Color customColor = inputNode.getCustomColor();
if (customColor != null) {
return customColor;
} else {
return color; return color;
} }
}
public void setWarning(String warning) { public void setWarning(String warning) {
this.warning = getProperties().resolveString(warning); this.warning = getProperties().resolveString(warning);
@ -415,4 +421,16 @@ public class Figure extends Properties.Entity implements Vertex {
public int compareTo(Vertex f) { public int compareTo(Vertex f) {
return toString().compareTo(f.toString()); return toString().compareTo(f.toString());
} }
public void setCustomColor(Color color) {
// Apply custom color not just to this input node but to all
// corresponding input nodes in the group.
InputGraph graph = diagram.getInputGraph();
for (InputGraph g : graph.getGroup().getGraphs()) {
InputNode n = g.getNode(inputNode.getId());
if (n != null) {
n.setCustomColor(color);
}
}
}
} }

View file

@ -230,7 +230,7 @@ public class DiagramScene extends ObjectScene implements DiagramViewer, DoubleCl
public void colorSelectedFigures(Color color) { public void colorSelectedFigures(Color color) {
for (Figure figure : model.getSelectedFigures()) { for (Figure figure : model.getSelectedFigures()) {
figure.setColor(color); figure.setCustomColor(color);
FigureWidget figureWidget = getWidget(figure); FigureWidget figureWidget = getWidget(figure);
if (figureWidget != null) { if (figureWidget != null) {
figureWidget.refreshColor(); figureWidget.refreshColor();

View file

@ -82,6 +82,7 @@ public final class ColorAction extends ModelAwareAction {
private static final JLabel selectedColorLabel = new JLabel("Preview"); private static final JLabel selectedColorLabel = new JLabel("Preview");
private static final JColorChooser colorChooser = new JColorChooser(Color.WHITE); private static final JColorChooser colorChooser = new JColorChooser(Color.WHITE);
private static final Color NO_COLOR = new Color(0, 0, 0, 0);
public ColorAction() { public ColorAction() {
initializeComponents(); initializeComponents();
@ -89,8 +90,8 @@ public final class ColorAction extends ModelAwareAction {
private void initializeComponents() { private void initializeComponents() {
selectedColorLabel.setPreferredSize(new Dimension(3 * 32, 32)); selectedColorLabel.setPreferredSize(new Dimension(3 * 32, 32));
selectedColorLabel.setOpaque(true); selectedColorLabel.setOpaque(false); // Allow transparency
selectedColorLabel.setBackground(Color.WHITE); selectedColorLabel.setBackground(NO_COLOR); // Set transparent background
selectedColorLabel.setForeground(Color.BLACK); // Set text color selectedColorLabel.setForeground(Color.BLACK); // Set text color
selectedColorLabel.setHorizontalAlignment(SwingConstants.CENTER); // Center the text selectedColorLabel.setHorizontalAlignment(SwingConstants.CENTER); // Center the text
@ -100,6 +101,7 @@ public final class ColorAction extends ModelAwareAction {
Color selectedColor = colorChooser.getColor(); Color selectedColor = colorChooser.getColor();
if (selectedColor != null) { if (selectedColor != null) {
selectedColorLabel.setBackground(selectedColor); selectedColorLabel.setBackground(selectedColor);
selectedColorLabel.setOpaque(selectedColor.getAlpha() != 0);
selectedColorLabel.setForeground(FigureWidget.getTextColor(selectedColor)); selectedColorLabel.setForeground(FigureWidget.getTextColor(selectedColor));
} }
}); });
@ -118,10 +120,27 @@ public final class ColorAction extends ModelAwareAction {
colorButton.setPreferredSize(new Dimension(16, 16)); colorButton.setPreferredSize(new Dimension(16, 16));
colorButton.addActionListener(e -> { colorButton.addActionListener(e -> {
selectedColorLabel.setBackground(color); selectedColorLabel.setBackground(color);
selectedColorLabel.setOpaque(color.getAlpha() != 0);
selectedColorLabel.setForeground(FigureWidget.getTextColor(color)); selectedColorLabel.setForeground(FigureWidget.getTextColor(color));
}); });
colorsPanel.add(colorButton); colorsPanel.add(colorButton);
} }
// Add "No Color" button
JButton noColorButton = new JButton("No Color");
noColorButton.setOpaque(true);
noColorButton.setContentAreaFilled(true);
noColorButton.setBorderPainted(true);
noColorButton.setPreferredSize(new Dimension(90, 24));
noColorButton.setFocusPainted(false);
noColorButton.addActionListener(e -> {
selectedColorLabel.setBackground(NO_COLOR);
selectedColorLabel.setOpaque(false);
selectedColorLabel.setForeground(Color.BLACK);
});
colorsPanel.add(noColorButton);
// Add the preview label
colorsPanel.add(selectedColorLabel, 0); colorsPanel.add(selectedColorLabel, 0);
colorsPanel.revalidate(); colorsPanel.revalidate();
colorsPanel.repaint(); colorsPanel.repaint();
@ -148,9 +167,10 @@ public final class ColorAction extends ModelAwareAction {
dialogLoc = dialogHolder[0].getLocation(); dialogLoc = dialogHolder[0].getLocation();
// OK button action // OK button action
Color selectedColor = selectedColorLabel.getBackground(); Color selectedColor = selectedColorLabel.getBackground();
if (selectedColor != null) { if (selectedColor.equals(NO_COLOR)) {
editor.colorSelectedFigures(selectedColor); selectedColor = null;
} }
editor.colorSelectedFigures(selectedColor);
}, },
null // Cancel button action null // Cancel button action
); );

View file

@ -271,6 +271,7 @@ public class FigureWidget extends Widget implements Properties.Provider, PopupMe
@Override @Override
protected void paintChildren() { protected void paintChildren() {
refreshColor();
Composite oldComposite = null; Composite oldComposite = null;
if (boundary) { if (boundary) {
oldComposite = getScene().getGraphics().getComposite(); oldComposite = getScene().getGraphics().getComposite();