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.
|
||||
*
|
||||
* 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() {
|
||||
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.
|
||||
*
|
||||
* 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.InputNode;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.*;
|
||||
import java.util.Collection;
|
||||
import javax.swing.JComponent;
|
||||
import org.openide.awt.UndoRedo;
|
||||
@ -89,4 +86,6 @@ public interface DiagramViewer {
|
||||
Rectangle getBounds();
|
||||
|
||||
JComponent getView();
|
||||
|
||||
void colorSelectedFigures(Color color);
|
||||
}
|
||||
|
@ -99,6 +99,7 @@ public final class EditorTopComponent extends TopComponent implements TopCompone
|
||||
};
|
||||
|
||||
Action[] actionsWithSelection = new Action[]{
|
||||
ColorAction.get(ColorAction.class),
|
||||
ExtractAction.get(ExtractAction.class),
|
||||
HideAction.get(HideAction.class),
|
||||
null,
|
||||
@ -349,6 +350,10 @@ public final class EditorTopComponent extends TopComponent implements TopCompone
|
||||
scene.addSelectedNodes(nodes, showIfHidden);
|
||||
}
|
||||
|
||||
public void colorSelectedFigures(Color color) {
|
||||
scene.colorSelectedFigures(color);
|
||||
}
|
||||
|
||||
public void centerSelectedNodes() {
|
||||
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.
|
||||
*
|
||||
* 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")
|
||||
})
|
||||
@Messages({
|
||||
"CTL_ExtractAction=Extract action",
|
||||
"CTL_ExtractAction=Extract",
|
||||
"HINT_ExtractAction=Extract current set of selected nodes"
|
||||
})
|
||||
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.
|
||||
*
|
||||
* 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) {
|
||||
LabelWidget extraLabelWidget = labelWidgets.get(labelWidgets.size() - 1);
|
||||
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.CENTER;
|
||||
middleWidget.setLayout(LayoutFactory.createVerticalFlowLayout(textAlign, 0));
|
||||
middleWidget.setBackground(f.getColor());
|
||||
middleWidget.setOpaque(true);
|
||||
middleWidget.getActions().addAction(new DoubleClickAction(this));
|
||||
middleWidget.setCheckClipping(false);
|
||||
@ -143,13 +155,13 @@ public class FigureWidget extends Widget implements Properties.Provider, PopupMe
|
||||
textWidget.addChild(lw);
|
||||
lw.setLabel(displayString);
|
||||
lw.setFont(Diagram.FONT);
|
||||
lw.setForeground(getTextColor());
|
||||
lw.setAlignment(LabelWidget.Alignment.CENTER);
|
||||
lw.setVerticalAlignment(LabelWidget.VerticalAlignment.CENTER);
|
||||
lw.setBorder(BorderFactory.createEmptyBorder());
|
||||
lw.setCheckClipping(false);
|
||||
}
|
||||
formatExtraLabel(false);
|
||||
refreshColor();
|
||||
|
||||
if (getFigure().getWarning() != null) {
|
||||
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()));
|
||||
}
|
||||
|
||||
public void refreshColor() {
|
||||
middleWidget.setBackground(figure.getColor());
|
||||
for (LabelWidget lw : labelWidgets) {
|
||||
lw.setForeground(getTextColor(figure.getColor()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
|
||||
super.notifyStateChanged(previousState, state);
|
||||
@ -222,16 +241,6 @@ public class FigureWidget extends Widget implements Properties.Provider, PopupMe
|
||||
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
|
||||
protected void paintChildren() {
|
||||
Composite oldComposite = null;
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 207 B |
Loading…
Reference in New Issue
Block a user