8343535: IGV: Colorize nodes on demand
Co-authored-by: Roberto Castañeda Lozano <rcastanedalo@openjdk.org> Reviewed-by: chagedorn, rcastanedalo
This commit is contained in:
parent
5016132291
commit
f3ba767604
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -222,6 +222,17 @@ public class DiagramScene extends ObjectScene implements DiagramViewer, DoubleCl
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public void colorSelectedFigures(Color color) {
|
||||||
|
for (Figure figure : model.getSelectedFigures()) {
|
||||||
|
figure.setColor(color);
|
||||||
|
FigureWidget figureWidget = getWidget(figure);
|
||||||
|
if (figureWidget != null) {
|
||||||
|
figureWidget.refreshColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
validateAll();
|
||||||
|
}
|
||||||
|
|
||||||
private Point getScrollPosition() {
|
private Point getScrollPosition() {
|
||||||
return scrollPane.getViewport().getViewPosition();
|
return scrollPane.getViewport().getViewPosition();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,10 +26,7 @@ package com.sun.hotspot.igv.view;
|
|||||||
|
|
||||||
import com.sun.hotspot.igv.data.ChangedEvent;
|
import com.sun.hotspot.igv.data.ChangedEvent;
|
||||||
import com.sun.hotspot.igv.data.InputNode;
|
import com.sun.hotspot.igv.data.InputNode;
|
||||||
import java.awt.Component;
|
import java.awt.*;
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.Point;
|
|
||||||
import java.awt.Rectangle;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import org.openide.awt.UndoRedo;
|
import org.openide.awt.UndoRedo;
|
||||||
@ -89,4 +86,6 @@ public interface DiagramViewer {
|
|||||||
Rectangle getBounds();
|
Rectangle getBounds();
|
||||||
|
|
||||||
JComponent getView();
|
JComponent getView();
|
||||||
|
|
||||||
|
void colorSelectedFigures(Color color);
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,7 @@ public final class EditorTopComponent extends TopComponent implements TopCompone
|
|||||||
};
|
};
|
||||||
|
|
||||||
Action[] actionsWithSelection = new Action[]{
|
Action[] actionsWithSelection = new Action[]{
|
||||||
|
ColorAction.get(ColorAction.class),
|
||||||
ExtractAction.get(ExtractAction.class),
|
ExtractAction.get(ExtractAction.class),
|
||||||
HideAction.get(HideAction.class),
|
HideAction.get(HideAction.class),
|
||||||
null,
|
null,
|
||||||
@ -349,6 +350,10 @@ public final class EditorTopComponent extends TopComponent implements TopCompone
|
|||||||
scene.addSelectedNodes(nodes, showIfHidden);
|
scene.addSelectedNodes(nodes, showIfHidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void colorSelectedFigures(Color color) {
|
||||||
|
scene.colorSelectedFigures(color);
|
||||||
|
}
|
||||||
|
|
||||||
public void centerSelectedNodes() {
|
public void centerSelectedNodes() {
|
||||||
scene.centerSelectedFigures();
|
scene.centerSelectedFigures();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.sun.hotspot.igv.view.actions;
|
||||||
|
|
||||||
|
import com.sun.hotspot.igv.view.DiagramViewModel;
|
||||||
|
import com.sun.hotspot.igv.view.EditorTopComponent;
|
||||||
|
import com.sun.hotspot.igv.view.widgets.FigureWidget;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import javax.swing.*;
|
||||||
|
import org.openide.awt.ActionID;
|
||||||
|
import org.openide.awt.ActionReference;
|
||||||
|
import org.openide.awt.ActionReferences;
|
||||||
|
import org.openide.awt.ActionRegistration;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
|
||||||
|
|
||||||
|
@ActionID(category = "View", id = "com.sun.hotspot.igv.view.actions.ColorAction")
|
||||||
|
@ActionRegistration(displayName = "#CTL_ColorAction")
|
||||||
|
@ActionReferences({
|
||||||
|
@ActionReference(path = "Menu/View", position = 360),
|
||||||
|
@ActionReference(path = "Shortcuts", name = "D-C")
|
||||||
|
})
|
||||||
|
@Messages({
|
||||||
|
"CTL_ColorAction=Color",
|
||||||
|
"HINT_ColorAction=Color current set of selected nodes"
|
||||||
|
})
|
||||||
|
public final class ColorAction extends ModelAwareAction {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String iconResource() {
|
||||||
|
return "com/sun/hotspot/igv/view/images/color.gif"; // NOI18N
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getDescription() {
|
||||||
|
return NbBundle.getMessage(ColorAction.class, "HINT_ColorAction");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return NbBundle.getMessage(ColorAction.class, "CTL_ColorAction");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ArrayList<Color> colors = new ArrayList<>(Arrays.asList(
|
||||||
|
Color.RED,
|
||||||
|
Color.ORANGE,
|
||||||
|
Color.YELLOW,
|
||||||
|
Color.GREEN,
|
||||||
|
Color.CYAN,
|
||||||
|
Color.BLUE,
|
||||||
|
Color.MAGENTA,
|
||||||
|
Color.PINK,
|
||||||
|
Color.DARK_GRAY,
|
||||||
|
Color.GRAY,
|
||||||
|
Color.LIGHT_GRAY,
|
||||||
|
Color.WHITE
|
||||||
|
));
|
||||||
|
|
||||||
|
private static final JLabel selectedColorLabel = new JLabel("Preview");
|
||||||
|
private static final JColorChooser colorChooser = new JColorChooser(Color.WHITE);
|
||||||
|
|
||||||
|
public ColorAction() {
|
||||||
|
initializeComponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeComponents() {
|
||||||
|
selectedColorLabel.setPreferredSize(new Dimension(3 * 32, 32));
|
||||||
|
selectedColorLabel.setOpaque(true);
|
||||||
|
selectedColorLabel.setBackground(Color.WHITE);
|
||||||
|
selectedColorLabel.setForeground(Color.BLACK); // Set text color
|
||||||
|
selectedColorLabel.setHorizontalAlignment(SwingConstants.CENTER); // Center the text
|
||||||
|
|
||||||
|
|
||||||
|
// Add a ChangeListener to react to color selection changes
|
||||||
|
colorChooser.getSelectionModel().addChangeListener(e -> {
|
||||||
|
Color selectedColor = colorChooser.getColor();
|
||||||
|
if (selectedColor != null) {
|
||||||
|
selectedColorLabel.setBackground(selectedColor);
|
||||||
|
selectedColorLabel.setForeground(FigureWidget.getTextColor(selectedColor));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create a panel to display recent colors
|
||||||
|
JPanel colorsPanel = new JPanel();
|
||||||
|
colorsPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
|
||||||
|
for (Color color : colors) {
|
||||||
|
JButton colorButton = new JButton();
|
||||||
|
colorButton.setBackground(color);
|
||||||
|
colorButton.setOpaque(true);
|
||||||
|
colorButton.setBorderPainted(false);
|
||||||
|
colorButton.setRolloverEnabled(false);
|
||||||
|
colorButton.setRequestFocusEnabled(false);
|
||||||
|
|
||||||
|
colorButton.setPreferredSize(new Dimension(16, 16));
|
||||||
|
colorButton.addActionListener(e -> {
|
||||||
|
selectedColorLabel.setBackground(color);
|
||||||
|
selectedColorLabel.setForeground(FigureWidget.getTextColor(color));
|
||||||
|
});
|
||||||
|
colorsPanel.add(colorButton);
|
||||||
|
}
|
||||||
|
colorsPanel.add(selectedColorLabel, 0);
|
||||||
|
colorsPanel.revalidate();
|
||||||
|
colorsPanel.repaint();
|
||||||
|
|
||||||
|
// Add recent colors panel below the color chooser
|
||||||
|
colorChooser.setPreviewPanel(colorsPanel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variables to store the dialog position
|
||||||
|
private Point dialogLoc = null;
|
||||||
|
|
||||||
|
public void performAction(DiagramViewModel model) {
|
||||||
|
EditorTopComponent editor = EditorTopComponent.getActive();
|
||||||
|
if (editor != null) {
|
||||||
|
// Create the dialog with an OK button to select the color
|
||||||
|
final JDialog[] dialogHolder = new JDialog[1];
|
||||||
|
dialogHolder[0] = JColorChooser.createDialog(
|
||||||
|
null,
|
||||||
|
"Choose a Color",
|
||||||
|
true,
|
||||||
|
colorChooser,
|
||||||
|
e -> {
|
||||||
|
// Save the current location
|
||||||
|
dialogLoc = dialogHolder[0].getLocation();
|
||||||
|
// OK button action
|
||||||
|
Color selectedColor = selectedColorLabel.getBackground();
|
||||||
|
if (selectedColor != null) {
|
||||||
|
editor.colorSelectedFigures(selectedColor);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
null // Cancel button action
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set the dialog's position if previously saved
|
||||||
|
if (dialogLoc != null) {
|
||||||
|
dialogHolder[0].setLocation(dialogLoc);
|
||||||
|
}
|
||||||
|
dialogHolder[0].setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled(DiagramViewModel model) {
|
||||||
|
return model != null && !model.getSelectedNodes().isEmpty();
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -42,7 +42,7 @@ import org.openide.util.NbBundle.Messages;
|
|||||||
@ActionReference(path = "Shortcuts", name = "D-X")
|
@ActionReference(path = "Shortcuts", name = "D-X")
|
||||||
})
|
})
|
||||||
@Messages({
|
@Messages({
|
||||||
"CTL_ExtractAction=Extract action",
|
"CTL_ExtractAction=Extract",
|
||||||
"HINT_ExtractAction=Extract current set of selected nodes"
|
"HINT_ExtractAction=Extract current set of selected nodes"
|
||||||
})
|
})
|
||||||
public final class ExtractAction extends ModelAwareAction {
|
public final class ExtractAction extends ModelAwareAction {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -90,7 +90,20 @@ public class FigureWidget extends Widget implements Properties.Provider, PopupMe
|
|||||||
if (getFigure().getProperties().get("extra_label") != null) {
|
if (getFigure().getProperties().get("extra_label") != null) {
|
||||||
LabelWidget extraLabelWidget = labelWidgets.get(labelWidgets.size() - 1);
|
LabelWidget extraLabelWidget = labelWidgets.get(labelWidgets.size() - 1);
|
||||||
extraLabelWidget.setFont(Diagram.FONT.deriveFont(Font.ITALIC));
|
extraLabelWidget.setFont(Diagram.FONT.deriveFont(Font.ITALIC));
|
||||||
extraLabelWidget.setForeground(selected ? getTextColor() : Color.DARK_GRAY);
|
extraLabelWidget.setForeground(getTextColorHelper(figure.getColor(), !selected));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color getTextColor(Color color) {
|
||||||
|
return getTextColorHelper(color, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Color getTextColorHelper(Color bg, boolean useGrey) {
|
||||||
|
double brightness = bg.getRed() * 0.21 + bg.getGreen() * 0.72 + bg.getBlue() * 0.07;
|
||||||
|
if (brightness < 150) {
|
||||||
|
return useGrey ? Color.LIGHT_GRAY : Color.WHITE;
|
||||||
|
} else {
|
||||||
|
return useGrey ? Color.DARK_GRAY : Color.BLACK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +126,6 @@ public class FigureWidget extends Widget implements Properties.Provider, PopupMe
|
|||||||
LayoutFactory.SerialAlignment.LEFT_TOP :
|
LayoutFactory.SerialAlignment.LEFT_TOP :
|
||||||
LayoutFactory.SerialAlignment.CENTER;
|
LayoutFactory.SerialAlignment.CENTER;
|
||||||
middleWidget.setLayout(LayoutFactory.createVerticalFlowLayout(textAlign, 0));
|
middleWidget.setLayout(LayoutFactory.createVerticalFlowLayout(textAlign, 0));
|
||||||
middleWidget.setBackground(f.getColor());
|
|
||||||
middleWidget.setOpaque(true);
|
middleWidget.setOpaque(true);
|
||||||
middleWidget.getActions().addAction(new DoubleClickAction(this));
|
middleWidget.getActions().addAction(new DoubleClickAction(this));
|
||||||
middleWidget.setCheckClipping(false);
|
middleWidget.setCheckClipping(false);
|
||||||
@ -143,13 +155,13 @@ public class FigureWidget extends Widget implements Properties.Provider, PopupMe
|
|||||||
textWidget.addChild(lw);
|
textWidget.addChild(lw);
|
||||||
lw.setLabel(displayString);
|
lw.setLabel(displayString);
|
||||||
lw.setFont(Diagram.FONT);
|
lw.setFont(Diagram.FONT);
|
||||||
lw.setForeground(getTextColor());
|
|
||||||
lw.setAlignment(LabelWidget.Alignment.CENTER);
|
lw.setAlignment(LabelWidget.Alignment.CENTER);
|
||||||
lw.setVerticalAlignment(LabelWidget.VerticalAlignment.CENTER);
|
lw.setVerticalAlignment(LabelWidget.VerticalAlignment.CENTER);
|
||||||
lw.setBorder(BorderFactory.createEmptyBorder());
|
lw.setBorder(BorderFactory.createEmptyBorder());
|
||||||
lw.setCheckClipping(false);
|
lw.setCheckClipping(false);
|
||||||
}
|
}
|
||||||
formatExtraLabel(false);
|
formatExtraLabel(false);
|
||||||
|
refreshColor();
|
||||||
|
|
||||||
if (getFigure().getWarning() != null) {
|
if (getFigure().getWarning() != null) {
|
||||||
ImageWidget warningWidget = new ImageWidget(scene, warningSign);
|
ImageWidget warningWidget = new ImageWidget(scene, warningSign);
|
||||||
@ -184,6 +196,13 @@ public class FigureWidget extends Widget implements Properties.Provider, PopupMe
|
|||||||
this.setToolTipText(PropertiesConverter.convertToHTML(f.getProperties()));
|
this.setToolTipText(PropertiesConverter.convertToHTML(f.getProperties()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void refreshColor() {
|
||||||
|
middleWidget.setBackground(figure.getColor());
|
||||||
|
for (LabelWidget lw : labelWidgets) {
|
||||||
|
lw.setForeground(getTextColor(figure.getColor()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
|
protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
|
||||||
super.notifyStateChanged(previousState, state);
|
super.notifyStateChanged(previousState, state);
|
||||||
@ -222,16 +241,6 @@ public class FigureWidget extends Widget implements Properties.Provider, PopupMe
|
|||||||
return figure;
|
return figure;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color getTextColor() {
|
|
||||||
Color bg = figure.getColor();
|
|
||||||
double brightness = bg.getRed() * 0.21 + bg.getGreen() * 0.72 + bg.getBlue() * 0.07;
|
|
||||||
if (brightness < 150) {
|
|
||||||
return Color.WHITE;
|
|
||||||
} else {
|
|
||||||
return Color.BLACK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintChildren() {
|
protected void paintChildren() {
|
||||||
Composite oldComposite = null;
|
Composite oldComposite = null;
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 207 B |
Loading…
Reference in New Issue
Block a user