8344204: IGV: Button to enable/disable cutting of long edges
Reviewed-by: rcastanedalo, chagedorn
This commit is contained in:
parent
4a7ce1d7c1
commit
6c2ae44c05
@ -45,6 +45,12 @@ public class HierarchicalCFGLayoutManager implements LayoutManager {
|
||||
fontMetrics = canvas.getFontMetrics(font);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCutEdges(boolean enable) {
|
||||
subManager.setCutEdges(enable);
|
||||
manager.setCutEdges(enable);
|
||||
}
|
||||
|
||||
public void setSubManager(LayoutManager manager) {
|
||||
this.subManager = manager;
|
||||
}
|
||||
|
@ -43,6 +43,12 @@ public class HierarchicalClusterLayoutManager implements LayoutManager {
|
||||
this.combine = combine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCutEdges(boolean enable) {
|
||||
subManager.setCutEdges(enable);
|
||||
manager.setCutEdges(enable);
|
||||
}
|
||||
|
||||
public void doLayout(LayoutGraph graph, Set<? extends Link> importantLinks) {
|
||||
doLayout(graph);
|
||||
}
|
||||
|
@ -136,8 +136,9 @@ public class HierarchicalLayoutManager implements LayoutManager {
|
||||
this.layerOffset = layerOffset;
|
||||
}
|
||||
|
||||
public void setMaxLayerLength(int v) {
|
||||
maxLayerLength = v;
|
||||
@Override
|
||||
public void setCutEdges(boolean enable) {
|
||||
maxLayerLength = enable ? 10 : -1;
|
||||
}
|
||||
|
||||
public void setMinLayerDifference(int v) {
|
||||
|
@ -38,8 +38,8 @@ public class HierarchicalStableLayoutManager {
|
||||
public static final int X_OFFSET = 8;
|
||||
public static final int LAYER_OFFSET = 8;
|
||||
// Algorithm global data structures
|
||||
private HashSet<? extends Vertex> currentVertices;
|
||||
private HashSet<? extends Link> currentLinks;
|
||||
private Set<? extends Vertex> currentVertices;
|
||||
private Set<? extends Link> currentLinks;
|
||||
private Set<Link> reversedLinks;
|
||||
private List<LayoutNode> nodes;
|
||||
private final HashMap<Vertex, LayoutNode> vertexToLayoutNode;
|
||||
@ -51,10 +51,19 @@ public class HierarchicalStableLayoutManager {
|
||||
private HashMap<Vertex, VertexAction> vertexToAction;
|
||||
private List<VertexAction> vertexActions;
|
||||
private List<LinkAction> linkActions;
|
||||
private HashSet<? extends Vertex> oldVertices;
|
||||
private HashSet<? extends Link> oldLinks;
|
||||
private Set<? extends Vertex> oldVertices;
|
||||
private Set<? extends Link> oldLinks;
|
||||
private boolean shouldRedrawLayout = true;
|
||||
private boolean shouldRemoveEmptyLayers = true;
|
||||
private boolean cutEdges = false;
|
||||
|
||||
public void doLayout(LayoutGraph layoutGraph) {
|
||||
boolean oldShouldRedrawLayout = shouldRedrawLayout;
|
||||
setShouldRedrawLayout(true);
|
||||
updateLayout(layoutGraph.getVertices(), layoutGraph.getLinks());
|
||||
setShouldRedrawLayout(oldShouldRedrawLayout);
|
||||
}
|
||||
|
||||
|
||||
enum Action {
|
||||
ADD,
|
||||
@ -90,6 +99,15 @@ public class HierarchicalStableLayoutManager {
|
||||
nodes = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void setCutEdges(boolean enable) {
|
||||
cutEdges = enable;
|
||||
manager.setCutEdges(enable);
|
||||
}
|
||||
|
||||
public boolean getCutEdges() {
|
||||
return cutEdges;
|
||||
}
|
||||
|
||||
private int calculateOptimalBoth(LayoutNode n) {
|
||||
if (n.preds.isEmpty() && n.succs.isEmpty()) {
|
||||
return n.x;
|
||||
@ -396,7 +414,7 @@ public class HierarchicalStableLayoutManager {
|
||||
this.shouldRedrawLayout = shouldRedrawLayout;
|
||||
}
|
||||
|
||||
public void updateLayout(HashSet<? extends Vertex> vertices, HashSet<? extends Link> links) {
|
||||
public void updateLayout(Set<? extends Vertex> vertices, Set<? extends Link> links) {
|
||||
currentVertices = vertices;
|
||||
currentLinks = links;
|
||||
reversedLinks = new HashSet<>();
|
||||
|
@ -39,6 +39,9 @@ public class LinearLayoutManager implements LayoutManager {
|
||||
this.vertexRank = vertexRank;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCutEdges(boolean enable) {}
|
||||
|
||||
@Override
|
||||
public void doLayout(LayoutGraph graph) {
|
||||
doLayout(graph, new HashSet<>());
|
||||
|
@ -31,6 +31,8 @@ import java.util.Set;
|
||||
*/
|
||||
public interface LayoutManager {
|
||||
|
||||
void setCutEdges(boolean enable);
|
||||
|
||||
void doLayout(LayoutGraph graph);
|
||||
|
||||
void doLayout(LayoutGraph graph, Set<? extends Link> importantLinks);
|
||||
|
@ -700,12 +700,19 @@ public class DiagramScene extends ObjectScene implements DiagramViewer, DoubleCl
|
||||
}
|
||||
|
||||
private void doStableSeaLayout(HashSet<Figure> visibleFigures, HashSet<Connection> visibleConnections) {
|
||||
hierarchicalStableLayoutManager.updateLayout(visibleFigures, visibleConnections);
|
||||
boolean enable = model.getCutEdges();
|
||||
boolean previous = hierarchicalStableLayoutManager.getCutEdges();
|
||||
hierarchicalStableLayoutManager.setCutEdges(enable);
|
||||
if (enable != previous) {
|
||||
hierarchicalStableLayoutManager.doLayout(new LayoutGraph(visibleConnections, visibleFigures));
|
||||
} else {
|
||||
hierarchicalStableLayoutManager.updateLayout(visibleFigures, visibleConnections);
|
||||
}
|
||||
}
|
||||
|
||||
private void doSeaLayout(HashSet<Figure> figures, HashSet<Connection> edges) {
|
||||
HierarchicalLayoutManager manager = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS);
|
||||
manager.setMaxLayerLength(10);
|
||||
manager.setCutEdges(model.getCutEdges());
|
||||
manager.doLayout(new LayoutGraph(edges, figures));
|
||||
hierarchicalStableLayoutManager.setShouldRedrawLayout(true);
|
||||
}
|
||||
@ -713,7 +720,7 @@ public class DiagramScene extends ObjectScene implements DiagramViewer, DoubleCl
|
||||
private void doClusteredLayout(HashSet<Connection> edges) {
|
||||
HierarchicalClusterLayoutManager m = new HierarchicalClusterLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS);
|
||||
HierarchicalLayoutManager manager = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS);
|
||||
manager.setMaxLayerLength(9);
|
||||
manager.setCutEdges(model.getCutEdges());
|
||||
manager.setMinLayerDifference(3);
|
||||
m.setManager(manager);
|
||||
m.setSubManager(new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS));
|
||||
@ -724,7 +731,7 @@ public class DiagramScene extends ObjectScene implements DiagramViewer, DoubleCl
|
||||
Diagram diagram = getModel().getDiagram();
|
||||
HierarchicalCFGLayoutManager m = new HierarchicalCFGLayoutManager();
|
||||
HierarchicalLayoutManager manager = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS);
|
||||
manager.setMaxLayerLength(9);
|
||||
manager.setCutEdges(model.getCutEdges());
|
||||
manager.setMinLayerDifference(1);
|
||||
manager.setLayoutSelfEdges(true);
|
||||
manager.setXOffset(25);
|
||||
|
@ -36,6 +36,7 @@ import com.sun.hotspot.igv.graph.Figure;
|
||||
import com.sun.hotspot.igv.graph.MatcherSelector;
|
||||
import com.sun.hotspot.igv.settings.Settings;
|
||||
import com.sun.hotspot.igv.util.RangeSliderModel;
|
||||
import com.sun.hotspot.igv.view.actions.CutEdgesAction;
|
||||
import com.sun.hotspot.igv.view.actions.GlobalSelectionAction;
|
||||
import java.awt.Color;
|
||||
import java.util.*;
|
||||
@ -68,8 +69,8 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
|
||||
private boolean showCFG;
|
||||
private boolean showNodeHull;
|
||||
private boolean showEmptyBlocks;
|
||||
private boolean hideDuplicates;
|
||||
private static boolean globalSelection = false;
|
||||
private static boolean cutEdges = false;
|
||||
|
||||
private final ChangedListener<FilterChain> filterChainChangedListener = changedFilterChain -> {
|
||||
assert filterChain == changedFilterChain;
|
||||
@ -80,6 +81,18 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
|
||||
return group;
|
||||
}
|
||||
|
||||
public boolean getCutEdges() {
|
||||
return cutEdges;
|
||||
}
|
||||
|
||||
public void setCutEdges(boolean enable, boolean fire) {
|
||||
boolean prevEnable = cutEdges;
|
||||
cutEdges = enable;
|
||||
if (fire && prevEnable != enable) {
|
||||
diagramChangedEvent.fire();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getGlobalSelection() {
|
||||
return globalSelection;
|
||||
}
|
||||
@ -154,25 +167,6 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
|
||||
diagramChangedEvent.fire();
|
||||
}
|
||||
|
||||
public void setHideDuplicates(boolean hideDuplicates) {
|
||||
this.hideDuplicates = hideDuplicates;
|
||||
InputGraph currentGraph = getFirstGraph();
|
||||
if (hideDuplicates) {
|
||||
// Back up to the unhidden equivalent graph
|
||||
int index = graphs.indexOf(currentGraph);
|
||||
while (graphs.get(index).getProperties().get("_isDuplicate") != null) {
|
||||
index--;
|
||||
}
|
||||
currentGraph = graphs.get(index);
|
||||
}
|
||||
filterGraphs();
|
||||
selectGraph(currentGraph);
|
||||
}
|
||||
|
||||
public boolean getHideDuplicates() {
|
||||
return hideDuplicates;
|
||||
}
|
||||
|
||||
private void initGroup() {
|
||||
group.getChangedEvent().addListener(g -> {
|
||||
assert g == group;
|
||||
@ -191,6 +185,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
|
||||
public DiagramViewModel(DiagramViewModel model) {
|
||||
super(model);
|
||||
globalSelection = false;
|
||||
cutEdges = false;
|
||||
group = model.getGroup();
|
||||
initGroup();
|
||||
graphs = new ArrayList<>(model.graphs);
|
||||
@ -205,12 +200,12 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
|
||||
filtersOrder = provider.getAllFiltersOrdered();
|
||||
|
||||
globalSelection = GlobalSelectionAction.get(GlobalSelectionAction.class).isSelected();
|
||||
cutEdges = CutEdgesAction.get(CutEdgesAction.class).isSelected();
|
||||
showCFG = model.getShowCFG();
|
||||
showSea = model.getShowSea();
|
||||
showBlocks = model.getShowBlocks();
|
||||
showNodeHull = model.getShowNodeHull();
|
||||
showEmptyBlocks = model.getShowEmptyBlocks();
|
||||
hideDuplicates = model.getHideDuplicates();
|
||||
|
||||
hiddenNodes = new HashSet<>(model.getHiddenNodes());
|
||||
selectedNodes = new HashSet<>();
|
||||
@ -228,13 +223,13 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
|
||||
filtersOrder = provider.getAllFiltersOrdered();
|
||||
|
||||
globalSelection = GlobalSelectionAction.get(GlobalSelectionAction.class).isSelected();
|
||||
cutEdges = CutEdgesAction.get(CutEdgesAction.class).isSelected();
|
||||
showStableSea = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.STABLE_SEA_OF_NODES;
|
||||
showSea = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.SEA_OF_NODES;
|
||||
showBlocks = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.CLUSTERED_SEA_OF_NODES;
|
||||
showCFG = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.CONTROL_FLOW_GRAPH;
|
||||
showNodeHull = true;
|
||||
showEmptyBlocks = true;
|
||||
hideDuplicates = false;
|
||||
|
||||
hiddenNodes = new HashSet<>();
|
||||
selectedNodes = new HashSet<>();
|
||||
@ -422,11 +417,8 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
|
||||
ArrayList<InputGraph> result = new ArrayList<>();
|
||||
List<String> positions = new ArrayList<>();
|
||||
for (InputGraph graph : group.getGraphs()) {
|
||||
String duplicate = graph.getProperties().get("_isDuplicate");
|
||||
if (duplicate == null || !hideDuplicates) {
|
||||
result.add(graph);
|
||||
positions.add(graph.getName());
|
||||
}
|
||||
result.add(graph);
|
||||
positions.add(graph.getName());
|
||||
}
|
||||
this.graphs = result;
|
||||
setPositions(positions);
|
||||
@ -460,22 +452,12 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
|
||||
|
||||
public void selectGraph(InputGraph graph) {
|
||||
int index = graphs.indexOf(graph);
|
||||
if (index == -1 && hideDuplicates) {
|
||||
// A graph was selected that's currently hidden, so unhide and select it.
|
||||
setHideDuplicates(false);
|
||||
index = graphs.indexOf(graph);
|
||||
}
|
||||
assert index != -1;
|
||||
setPositions(index, index);
|
||||
}
|
||||
|
||||
public void selectDiffGraph(InputGraph graph) {
|
||||
int index = graphs.indexOf(graph);
|
||||
if (index == -1 && hideDuplicates) {
|
||||
// A graph was selected that's currently hidden, so unhide and select it.
|
||||
setHideDuplicates(false);
|
||||
index = graphs.indexOf(graph);
|
||||
}
|
||||
assert index != -1;
|
||||
int firstIndex = getFirstPosition();
|
||||
int secondIndex = getSecondPosition();
|
||||
|
@ -210,7 +210,6 @@ public final class EditorTopComponent extends TopComponent implements TopCompone
|
||||
toolBar.addSeparator();
|
||||
toolBar.add(new JToggleButton(new PredSuccAction(diagramViewModel.getShowNodeHull())));
|
||||
toolBar.add(new JToggleButton(new ShowEmptyBlocksAction(cfgLayoutAction, diagramViewModel.getShowEmptyBlocks())));
|
||||
toolBar.add(new JToggleButton(new HideDuplicatesAction(diagramViewModel.getHideDuplicates())));
|
||||
|
||||
toolBar.addSeparator();
|
||||
UndoAction undoAction = UndoAction.get(UndoAction.class);
|
||||
@ -221,6 +220,11 @@ public final class EditorTopComponent extends TopComponent implements TopCompone
|
||||
toolBar.add(redoAction);
|
||||
|
||||
toolBar.addSeparator();
|
||||
|
||||
JToggleButton cutEdgesButton = new JToggleButton(CutEdgesAction.get(CutEdgesAction.class));
|
||||
cutEdgesButton.setHideActionText(true);
|
||||
toolBar.add(cutEdgesButton);
|
||||
|
||||
JToggleButton globalSelectionButton = new JToggleButton(GlobalSelectionAction.get(GlobalSelectionAction.class));
|
||||
globalSelectionButton.setHideActionText(true);
|
||||
toolBar.add(globalSelectionButton);
|
||||
@ -453,6 +457,7 @@ public final class EditorTopComponent extends TopComponent implements TopCompone
|
||||
}
|
||||
etc.addSelectedNodes(selectedNodes, false);
|
||||
model.setGlobalSelection(GlobalSelectionAction.get(GlobalSelectionAction.class).isSelected(), false);
|
||||
model.setCutEdges(CutEdgesAction.get(CutEdgesAction.class).isSelected(), false);
|
||||
etc.resetUndoRedo();
|
||||
|
||||
int currentZoomLevel = scene.getZoomPercentage();
|
||||
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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.EditorTopComponent;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.openide.awt.ActionID;
|
||||
import org.openide.awt.ActionReference;
|
||||
import org.openide.awt.ActionReferences;
|
||||
import org.openide.awt.ActionRegistration;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.ImageUtilities;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
|
||||
@ActionID(category = "View", id = "com.sun.hotspot.igv.view.actions.CutEdgesAction")
|
||||
@ActionRegistration(displayName = "#CTL_CutEdgesAction")
|
||||
@ActionReferences({
|
||||
@ActionReference(path = "Menu/Options", position = 350),
|
||||
})
|
||||
@NbBundle.Messages({
|
||||
"CTL_CutEdgesAction=Cut long edges",
|
||||
"HINT_CutEdgesAction=Cut long edges"
|
||||
})
|
||||
public final class CutEdgesAction extends CallableSystemAction {
|
||||
|
||||
private boolean isSelected;
|
||||
|
||||
public CutEdgesAction() {
|
||||
putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource())));
|
||||
putValue(Action.SHORT_DESCRIPTION, getDescription());
|
||||
putValue(SELECTED_KEY, false);
|
||||
isSelected = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NbBundle.getMessage(CutEdgesAction.class, "CTL_CutEdgesAction");
|
||||
}
|
||||
|
||||
@Override
|
||||
public HelpCtx getHelpCtx() {
|
||||
return HelpCtx.DEFAULT_HELP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performAction() {
|
||||
isSelected = !isSelected;
|
||||
putValue(SELECTED_KEY, isSelected);
|
||||
EditorTopComponent editor = EditorTopComponent.getActive();
|
||||
if (editor != null) {
|
||||
SwingUtilities.invokeLater(() -> editor.getModel().setCutEdges(isSelected, true));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSelected() {
|
||||
return isSelected;
|
||||
}
|
||||
|
||||
private String getDescription() {
|
||||
return NbBundle.getMessage(CutEdgesAction.class, "HINT_CutEdgesAction");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean asynchronous() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String iconResource() {
|
||||
return "com/sun/hotspot/igv/view/images/cut.png";
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2023, 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.EditorTopComponent;
|
||||
import java.awt.event.ActionEvent;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.ImageIcon;
|
||||
import org.openide.util.ImageUtilities;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Tom Rodriguez
|
||||
*/
|
||||
public class HideDuplicatesAction extends AbstractAction {
|
||||
|
||||
public HideDuplicatesAction(boolean selected) {
|
||||
putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource())));
|
||||
putValue(Action.SELECTED_KEY, selected);
|
||||
putValue(Action.SHORT_DESCRIPTION, "Hide graphs which are the same as the previous graph");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
EditorTopComponent editor = EditorTopComponent.getActive();
|
||||
if (editor != null) {
|
||||
boolean selected = (boolean)getValue(SELECTED_KEY);
|
||||
editor.getModel().setHideDuplicates(selected);
|
||||
}
|
||||
}
|
||||
|
||||
protected String iconResource() {
|
||||
return "com/sun/hotspot/igv/view/images/hideDuplicates.png";
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 618 B |
Loading…
Reference in New Issue
Block a user