Skip to content

Commit 4e7cb15

Browse files
committedSep 21, 2022
8293480: IGV: Update Bytecode and ControlFlow Component immediately when opening a new graph
Reviewed-by: rcastanedalo, chagedorn
1 parent 8ecdaa6 commit 4e7cb15

File tree

11 files changed

+200
-267
lines changed

11 files changed

+200
-267
lines changed
 

‎src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java

+40-50
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@
2323
*/
2424
package com.sun.hotspot.igv.bytecodes;
2525

26+
import com.sun.hotspot.igv.data.ChangedListener;
2627
import com.sun.hotspot.igv.data.Group;
2728
import com.sun.hotspot.igv.data.InputGraph;
2829
import com.sun.hotspot.igv.data.services.InputGraphProvider;
2930
import com.sun.hotspot.igv.util.LookupHistory;
3031
import java.awt.BorderLayout;
3132
import java.io.Serializable;
32-
import javax.swing.SwingUtilities;
3333
import org.openide.ErrorManager;
3434
import org.openide.explorer.ExplorerManager;
3535
import org.openide.explorer.ExplorerUtils;
@@ -41,13 +41,12 @@
4141
/**
4242
* @author Thomas Wuerthinger
4343
*/
44-
final class BytecodeViewTopComponent extends TopComponent implements ExplorerManager.Provider, LookupListener {
44+
final class BytecodeViewTopComponent extends TopComponent implements ExplorerManager.Provider, ChangedListener<InputGraphProvider> {
4545

4646
private static BytecodeViewTopComponent instance;
4747
private static final String PREFERRED_ID = "BytecodeViewTopComponent";
48-
private ExplorerManager manager;
49-
private BeanTreeView treeView;
50-
private Lookup.Result result = null;
48+
private final ExplorerManager manager;
49+
private final BeanTreeView treeView;
5150
private MethodNode rootNode;
5251

5352
private BytecodeViewTopComponent() {
@@ -67,32 +66,10 @@ private BytecodeViewTopComponent() {
6766
associateLookup(ExplorerUtils.createLookup(manager, getActionMap()));
6867
}
6968

70-
/** This method is called from within the constructor to
71-
* initialize the form.
72-
* WARNING: Do NOT modify this code. The content of this method is
73-
* always regenerated by the Form Editor.
74-
*/
75-
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
76-
private void initComponents() {
77-
78-
org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
79-
this.setLayout(layout);
80-
layout.setHorizontalGroup(
81-
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
82-
.add(0, 400, Short.MAX_VALUE)
83-
);
84-
layout.setVerticalGroup(
85-
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
86-
.add(0, 300, Short.MAX_VALUE)
87-
);
88-
}// </editor-fold>//GEN-END:initComponents
89-
// Variables declaration - do not modify//GEN-BEGIN:variables
90-
// End of variables declaration//GEN-END:variables
91-
9269
/**
9370
* Gets default instance. Do not use directly: reserved for *.settings files only,
9471
* i.e. deserialization routines; otherwise you could get a non-deserialized instance.
95-
* To obtain the singleton instance, use {@link findInstance}.
72+
* To obtain the singleton instance, use {@link #findInstance()}.
9673
*/
9774
public static synchronized BytecodeViewTopComponent getDefault() {
9875
if (instance == null) {
@@ -124,15 +101,12 @@ public int getPersistenceType() {
124101

125102
@Override
126103
public void componentOpened() {
127-
Lookup.Template<InputGraphProvider> tpl = new Lookup.Template<>(InputGraphProvider.class);
128-
result = Utilities.actionsGlobalContext().lookup(tpl);
129-
result.addLookupListener(this);
104+
LookupHistory.addListener(InputGraphProvider.class, this);
130105
}
131106

132107
@Override
133108
public void componentClosed() {
134-
result.removeLookupListener(this);
135-
result = null;
109+
LookupHistory.removeListener(InputGraphProvider.class, this);
136110
}
137111

138112
@Override
@@ -169,23 +143,17 @@ protected boolean requestFocusInWindow(boolean temporary) {
169143
}
170144

171145
@Override
172-
public void resultChanged(LookupEvent lookupEvent) {
173-
final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
174-
SwingUtilities.invokeLater(new Runnable() {
175-
@Override
176-
public void run() {
177-
if (p != null) {
178-
InputGraph graph = p.getGraph();
179-
if (graph != null) {
180-
Group g = graph.getGroup();
181-
rootNode.update(graph, g.getMethod());
182-
return;
183-
}
184-
}
185-
rootNode.update(null, null);
186-
}
187-
});
188-
146+
public void changed(InputGraphProvider lastProvider) {
147+
if (lastProvider != null) {
148+
InputGraph graph = lastProvider.getGraph();
149+
if (graph != null) {
150+
Group g = graph.getGroup();
151+
rootNode.update(graph, g.getMethod());
152+
return;
153+
}
154+
}
155+
rootNode = new MethodNode(null, null, "");
156+
manager.setRootContext(rootNode);
189157
}
190158

191159
static final class ResolvableHelper implements Serializable {
@@ -196,4 +164,26 @@ public Object readResolve() {
196164
return BytecodeViewTopComponent.getDefault();
197165
}
198166
}
167+
168+
/** This method is called from within the constructor to
169+
* initialize the form.
170+
* WARNING: Do NOT modify this code. The content of this method is
171+
* always regenerated by the Form Editor.
172+
*/
173+
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
174+
private void initComponents() {
175+
176+
org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
177+
this.setLayout(layout);
178+
layout.setHorizontalGroup(
179+
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
180+
.add(0, 400, Short.MAX_VALUE)
181+
);
182+
layout.setVerticalGroup(
183+
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
184+
.add(0, 300, Short.MAX_VALUE)
185+
);
186+
}// </editor-fold>//GEN-END:initComponents
187+
// Variables declaration - do not modify//GEN-BEGIN:variables
188+
// End of variables declaration//GEN-END:variables
199189
}

‎src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public final class SelectBytecodesAction extends CookieAction {
3939
@Override
4040
protected void performAction(Node[] activatedNodes) {
4141
SelectBytecodesCookie c = activatedNodes[0].getCookie(SelectBytecodesCookie.class);
42-
InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
42+
InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);
4343
if (p != null) {
4444
p.setSelectedNodes(c.getNodes());
4545
}

‎src/utils/IdealGraphVisualizer/ControlFlow/src/main/java/com/sun/hotspot/igv/controlflow/ControlFlowScene.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public void clearSelection() {
133133
}
134134

135135
public void selectionChanged() {
136-
InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
136+
InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);
137137
if (p != null) {
138138
Set<InputNode> inputNodes = new HashSet<InputNode>();
139139
for (BlockWidget w : selection) {

‎src/utils/IdealGraphVisualizer/ControlFlow/src/main/java/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java

+38-51
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,32 +23,27 @@
2323
*/
2424
package com.sun.hotspot.igv.controlflow;
2525

26+
import com.sun.hotspot.igv.data.ChangedListener;
2627
import com.sun.hotspot.igv.data.InputGraph;
2728
import com.sun.hotspot.igv.data.services.InputGraphProvider;
2829
import com.sun.hotspot.igv.util.LookupHistory;
2930
import java.awt.BorderLayout;
3031
import java.io.Serializable;
3132
import javax.swing.JScrollPane;
32-
import javax.swing.SwingUtilities;
3333
import org.openide.ErrorManager;
34-
import org.openide.util.Lookup;
35-
import org.openide.util.LookupEvent;
36-
import org.openide.util.LookupListener;
3734
import org.openide.util.NbBundle;
38-
import org.openide.util.Utilities;
3935
import org.openide.windows.TopComponent;
4036
import org.openide.windows.WindowManager;
4137

4238
/**
4339
*
4440
* @author Thomas Wuerthinger
4541
*/
46-
final class ControlFlowTopComponent extends TopComponent implements LookupListener {
42+
final class ControlFlowTopComponent extends TopComponent implements ChangedListener<InputGraphProvider> {
4743

4844
private static ControlFlowTopComponent instance;
49-
private Lookup.Result result = null;
5045
private static final String PREFERRED_ID = "ControlFlowTopComponent";
51-
private ControlFlowScene scene;
46+
private final ControlFlowScene scene;
5247

5348
private ControlFlowTopComponent() {
5449
initComponents();
@@ -64,34 +59,10 @@ private ControlFlowTopComponent() {
6459
this.add(panel, BorderLayout.CENTER);
6560
}
6661

67-
68-
69-
/** This method is called from within the constructor to
70-
* initialize the form.
71-
* WARNING: Do NOT modify this code. The content of this method is
72-
* always regenerated by the Form Editor.
73-
*/
74-
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
75-
private void initComponents() {
76-
77-
org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
78-
this.setLayout(layout);
79-
layout.setHorizontalGroup(
80-
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
81-
.add(0, 400, Short.MAX_VALUE)
82-
);
83-
layout.setVerticalGroup(
84-
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
85-
.add(0, 300, Short.MAX_VALUE)
86-
);
87-
}// </editor-fold>//GEN-END:initComponents
88-
// Variables declaration - do not modify//GEN-BEGIN:variables
89-
// End of variables declaration//GEN-END:variables
90-
9162
/**
9263
* Gets default instance. Do not use directly: reserved for *.settings files only,
9364
* i.e. deserialization routines; otherwise you could get a non-deserialized instance.
94-
* To obtain the singleton instance, use {@link findInstance}.
65+
* To obtain the singleton instance, use {@link #findInstance()}.
9566
*/
9667
public static synchronized ControlFlowTopComponent getDefault() {
9768
if (instance == null) {
@@ -123,30 +94,24 @@ public int getPersistenceType() {
12394

12495
@Override
12596
public void componentOpened() {
126-
Lookup.Template<InputGraphProvider> tpl = new Lookup.Template<InputGraphProvider>(InputGraphProvider.class);
127-
result = Utilities.actionsGlobalContext().lookup(tpl);
128-
result.addLookupListener(this);
97+
LookupHistory.addListener(InputGraphProvider.class, this);
12998
}
13099

131100
@Override
132101
public void componentClosed() {
133-
result.removeLookupListener(this);
134-
result = null;
102+
LookupHistory.removeListener(InputGraphProvider.class, this);
135103
}
136104

137-
public void resultChanged(LookupEvent lookupEvent) {
138-
final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
139-
if (p != null) {
140-
SwingUtilities.invokeLater(new Runnable() {
141-
142-
public void run() {
143-
InputGraph g = p.getGraph();
144-
if (g != null) {
145-
scene.setGraph(g);
146-
}
147-
}
148-
});
105+
@Override
106+
public void changed(InputGraphProvider lastProvider) {
107+
if (lastProvider != null) {
108+
InputGraph graph = lastProvider.getGraph();
109+
if (graph != null) {
110+
scene.setGraph(graph);
111+
return;
112+
}
149113
}
114+
scene.setGraph(new InputGraph(""));
150115
}
151116

152117
@Override
@@ -173,4 +138,26 @@ public Object readResolve() {
173138
return ControlFlowTopComponent.getDefault();
174139
}
175140
}
141+
142+
/** This method is called from within the constructor to
143+
* initialize the form.
144+
* WARNING: Do NOT modify this code. The content of this method is
145+
* always regenerated by the Form Editor.
146+
*/
147+
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
148+
private void initComponents() {
149+
150+
org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
151+
this.setLayout(layout);
152+
layout.setHorizontalGroup(
153+
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
154+
.add(0, 400, Short.MAX_VALUE)
155+
);
156+
layout.setVerticalGroup(
157+
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
158+
.add(0, 300, Short.MAX_VALUE)
159+
);
160+
}// </editor-fold>//GEN-END:initComponents
161+
// Variables declaration - do not modify//GEN-BEGIN:variables
162+
// End of variables declaration//GEN-END:variables
176163
}

‎src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java

+39-50
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525

2626
import com.sun.hotspot.igv.connection.Server;
2727
import com.sun.hotspot.igv.coordinator.actions.*;
28+
import com.sun.hotspot.igv.data.ChangedListener;
2829
import com.sun.hotspot.igv.data.GraphDocument;
29-
import com.sun.hotspot.igv.data.Group;
3030
import com.sun.hotspot.igv.data.InputGraph;
3131
import com.sun.hotspot.igv.data.services.GroupCallback;
3232
import com.sun.hotspot.igv.data.services.InputGraphProvider;
@@ -48,22 +48,21 @@
4848
import org.openide.explorer.ExplorerManager;
4949
import org.openide.explorer.ExplorerUtils;
5050
import org.openide.explorer.view.BeanTreeView;
51-
import org.openide.util.*;
52-
import org.openide.util.actions.NodeAction;
51+
import org.openide.util.Exceptions;
52+
import org.openide.util.NbBundle;
5353
import org.openide.windows.TopComponent;
5454
import org.openide.windows.WindowManager;
5555

5656
/**
5757
*
5858
* @author Thomas Wuerthinger
5959
*/
60-
public final class OutlineTopComponent extends TopComponent implements ExplorerManager.Provider, LookupListener {
60+
public final class OutlineTopComponent extends TopComponent implements ExplorerManager.Provider, ChangedListener<InputGraphProvider> {
6161

6262
public static OutlineTopComponent instance;
6363
public static final String PREFERRED_ID = "OutlineTopComponent";
64-
private Lookup.Result result = null;
6564
private ExplorerManager manager;
66-
private GraphDocument document;
65+
private final GraphDocument document;
6766
private FolderNode root;
6867
private Server server;
6968
private Server binaryServer;
@@ -100,13 +99,13 @@ private void initToolbar() {
10099
this.add(toolbar, BorderLayout.NORTH);
101100

102101
toolbar.add(ImportAction.get(ImportAction.class));
103-
toolbar.add(((NodeAction) SaveAsAction.get(SaveAsAction.class)).createContextAwareInstance(this.getLookup()));
102+
toolbar.add(SaveAsAction.get(SaveAsAction.class).createContextAwareInstance(this.getLookup()));
104103

105104
saveAllAction = SaveAllAction.get(SaveAllAction.class);
106105
saveAllAction.setEnabled(false);
107106
toolbar.add(saveAllAction);
108107

109-
toolbar.add(((NodeAction) RemoveAction.get(RemoveAction.class)).createContextAwareInstance(this.getLookup()));
108+
toolbar.add(RemoveAction.get(RemoveAction.class).createContextAwareInstance(this.getLookup()));
110109

111110
removeAllAction = RemoveAllAction.get(RemoveAllAction.class);
112111
removeAllAction.setEnabled(false);
@@ -129,43 +128,17 @@ private void documentChanged() {
129128

130129
private void initReceivers() {
131130

132-
final GroupCallback callback = new GroupCallback() {
133-
134-
@Override
135-
public void started(Group g) {
136-
synchronized(OutlineTopComponent.this) {
137-
getDocument().addElement(g);
138-
g.setParent(getDocument());
139-
}
131+
final GroupCallback callback = g -> {
132+
synchronized(OutlineTopComponent.this) {
133+
g.setParent(getDocument());
134+
getDocument().addElement(g);
140135
}
141136
};
142137

143138
server = new Server(getDocument(), callback, false);
144139
binaryServer = new Server(getDocument(), callback, true);
145140
}
146141

147-
// Fetch and select the latest active graph.
148-
private void updateGraphSelection() {
149-
final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);
150-
if (p != null) {
151-
try {
152-
InputGraph graph = p.getGraph();
153-
if (graph.isDiffGraph()) {
154-
EditorTopComponent editor = EditorTopComponent.getActive();
155-
if (editor != null) {
156-
InputGraph firstGraph = editor.getModel().getFirstGraph();
157-
InputGraph secondGraph = editor.getModel().getSecondGraph();
158-
manager.setSelectedNodes(new GraphNode[]{FolderNode.getGraphNode(firstGraph), FolderNode.getGraphNode(secondGraph)});
159-
}
160-
} else {
161-
manager.setSelectedNodes(new GraphNode[]{FolderNode.getGraphNode(graph)});
162-
}
163-
} catch (Exception e) {
164-
Exceptions.printStackTrace(e);
165-
}
166-
}
167-
}
168-
169142
public void clear() {
170143
document.clear();
171144
FolderNode.clearGraphNodeMap();
@@ -185,7 +158,7 @@ public GraphDocument getDocument() {
185158
/**
186159
* Gets default instance. Do not use directly: reserved for *.settings files only,
187160
* i.e. deserialization routines; otherwise you could get a non-deserialized instance.
188-
* To obtain the singleton instance, use {@link findInstance}.
161+
* To obtain the singleton instance, use {@link #findInstance()}.
189162
*/
190163
public static synchronized OutlineTopComponent getDefault() {
191164
if (instance == null) {
@@ -217,16 +190,13 @@ public int getPersistenceType() {
217190

218191
@Override
219192
public void componentOpened() {
220-
Lookup.Template<InputGraphProvider> tpl = new Lookup.Template<InputGraphProvider>(InputGraphProvider.class);
221-
result = Utilities.actionsGlobalContext().lookup(tpl);
222-
result.addLookupListener(this);
223-
updateGraphSelection();
193+
LookupHistory.addListener(InputGraphProvider.class, this);
224194
this.requestActive();
225195
}
226196

227197
@Override
228198
public void componentClosed() {
229-
result.removeLookupListener(this);
199+
LookupHistory.removeListener(InputGraphProvider.class, this);
230200
}
231201

232202
@Override
@@ -253,14 +223,33 @@ protected boolean requestFocusInWindow(boolean temporary) {
253223
}
254224

255225
@Override
256-
public void resultChanged(LookupEvent lookupEvent) {
257-
// Highlight the focused graph, if available, in the outline.
258-
if (result.allItems().isEmpty()) {
259-
return;
260-
}
226+
public void changed(InputGraphProvider lastProvider) {
261227
// Wait for LookupHistory to be updated with the last active graph
262228
// before selecting it.
263-
SwingUtilities.invokeLater(() -> updateGraphSelection());
229+
SwingUtilities.invokeLater(() -> {
230+
GraphNode[] selection = new GraphNode[0];
231+
if (lastProvider != null) {
232+
// Try to fetch and select the latest active graph.
233+
InputGraph graph = lastProvider.getGraph();
234+
if (graph != null) {
235+
if (graph.isDiffGraph()) {
236+
EditorTopComponent editor = EditorTopComponent.getActive();
237+
if (editor != null) {
238+
InputGraph firstGraph = editor.getModel().getFirstGraph();
239+
InputGraph secondGraph = editor.getModel().getSecondGraph();
240+
selection = new GraphNode[]{FolderNode.getGraphNode(firstGraph), FolderNode.getGraphNode(secondGraph)};
241+
}
242+
} else {
243+
selection = new GraphNode[]{FolderNode.getGraphNode(graph)};
244+
}
245+
}
246+
}
247+
try {
248+
manager.setSelectedNodes(selection);
249+
} catch (Exception e) {
250+
Exceptions.printStackTrace(e);
251+
}
252+
});
264253
}
265254

266255
@Override

‎src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ private void initComponents() {
546546
/**
547547
* Gets default instance. Do not use directly: reserved for *.settings files only,
548548
* i.e. deserialization routines; otherwise you could get a non-deserialized instance.
549-
* To obtain the singleton instance, use {@link findInstance}.
549+
* To obtain the singleton instance, use {@link #findInstance()}.
550550
*/
551551
public static synchronized FilterTopComponent getDefault() {
552552
if (instance == null) {

‎src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/services/DiagramProvider.java

-38
This file was deleted.

‎src/utils/IdealGraphVisualizer/Util/src/main/java/com/sun/hotspot/igv/util/LookupHistory.java

+33-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,8 @@
2323
*/
2424
package com.sun.hotspot.igv.util;
2525

26+
import com.sun.hotspot.igv.data.ChangedListener;
27+
import com.sun.hotspot.igv.data.Event;
2628
import java.util.HashMap;
2729
import java.util.Map;
2830
import org.openide.util.Lookup.Result;
@@ -38,7 +40,7 @@ public class LookupHistory {
3840

3941
private static Map<Class, LookupHistoryImpl> cache = new HashMap<>();
4042

41-
private static class LookupHistoryImpl<T> implements LookupListener {
43+
private static class LookupHistoryImpl<T> extends Event<ChangedListener<T>> implements LookupListener {
4244

4345
private Class<T> klass;
4446
private Result<T> result;
@@ -49,17 +51,25 @@ public LookupHistoryImpl(Class<T> klass) {
4951
result = Utilities.actionsGlobalContext().lookupResult(klass);
5052
result.addLookupListener(this);
5153
last = Utilities.actionsGlobalContext().lookup(klass);
54+
fire();
5255
}
5356

5457
public T getLast() {
5558
return last;
5659
}
5760

61+
@Override
62+
protected void fire(ChangedListener<T> l) {
63+
l.changed(last);
64+
}
65+
66+
5867
@Override
5968
public void resultChanged(LookupEvent ev) {
6069
T current = Utilities.actionsGlobalContext().lookup(klass);
6170
if (current != null) {
6271
last = current;
72+
this.fire();
6373
}
6474
}
6575
}
@@ -70,10 +80,31 @@ public static <T> void init(Class<T> klass) {
7080
}
7181
}
7282

83+
public static <T> void terminate(Class<T> klass) {
84+
if (cache.containsKey(klass)) {
85+
cache.get(klass).fire();
86+
}
87+
}
88+
7389
@SuppressWarnings("unchecked")
7490
public static <T> T getLast(Class<T> klass) {
7591
init(klass);
7692
assert cache.containsKey(klass);
7793
return (T) cache.get(klass).getLast();
7894
}
95+
96+
@SuppressWarnings("unchecked")
97+
public static <T> void addListener(Class<T> klass, ChangedListener<T> listener) {
98+
init(klass);
99+
assert cache.containsKey(klass);
100+
cache.get(klass).addListener(listener);
101+
cache.get(klass).fire();
102+
}
103+
104+
@SuppressWarnings("unchecked")
105+
public static <T> void removeListener(Class<T> klass, ChangedListener<T> listener) {
106+
if (cache.containsKey(klass)) {
107+
cache.get(klass).removeListener(listener);
108+
}
109+
}
79110
}

‎src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java

+10-23
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
6060
private FilterChain sequenceFilterChain;
6161
private Diagram diagram;
6262
private InputGraph inputGraph;
63-
private ChangedEvent<DiagramViewModel> groupChangedEvent;
6463
private ChangedEvent<DiagramViewModel> diagramChangedEvent;
6564
private ChangedEvent<DiagramViewModel> viewChangedEvent;
6665
private ChangedEvent<DiagramViewModel> hiddenNodesChangedEvent;
@@ -96,9 +95,14 @@ public void setData(DiagramViewModel newModel) {
9695
boolean viewChanged = false;
9796
boolean viewPropertiesChanged = false;
9897

99-
boolean groupChanged = (group == newModel.group);
100-
this.group = newModel.group;
101-
if (groupChanged) {
98+
if (group != newModel.group) {
99+
if (group != null) {
100+
group.getChangedEvent().removeListener(groupContentChangedListener);
101+
}
102+
group = newModel.group;
103+
if (group != null) {
104+
group.getChangedEvent().addListener(groupContentChangedListener);
105+
}
102106
filterGraphs();
103107
}
104108

@@ -123,10 +127,6 @@ public void setData(DiagramViewModel newModel) {
123127
viewPropertiesChanged |= (showNodeHull != newModel.showNodeHull);
124128
this.showNodeHull = newModel.showNodeHull;
125129

126-
if (groupChanged) {
127-
groupChangedEvent.fire();
128-
}
129-
130130
if (diagramChanged) {
131131
diagramChangedEvent.fire();
132132
}
@@ -213,6 +213,7 @@ public DiagramViewModel(Group g, FilterChain filterChain, FilterChain sequenceFi
213213
this.showNodeHull = true;
214214
this.showEmptyBlocks = true;
215215
this.group = g;
216+
group.getChangedEvent().addListener(groupContentChangedListener);
216217
filterGraphs();
217218
assert filterChain != null;
218219
this.filterChain = filterChain;
@@ -227,26 +228,11 @@ public DiagramViewModel(Group g, FilterChain filterChain, FilterChain sequenceFi
227228
hiddenNodesChangedEvent = new ChangedEvent<>(this);
228229
viewPropertiesChangedEvent = new ChangedEvent<>(this);
229230

230-
groupChangedEvent = new ChangedEvent<>(this);
231-
groupChangedEvent.addListener(groupChangedListener);
232-
groupChangedEvent.fire();
233231

234232
filterChain.getChangedEvent().addListener(filterChainChangedListener);
235233
sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
236234
}
237-
private final ChangedListener<DiagramViewModel> groupChangedListener = new ChangedListener<DiagramViewModel>() {
238-
239-
private Group oldGroup;
240235

241-
@Override
242-
public void changed(DiagramViewModel source) {
243-
if (oldGroup != null) {
244-
oldGroup.getChangedEvent().removeListener(groupContentChangedListener);
245-
}
246-
group.getChangedEvent().addListener(groupContentChangedListener);
247-
oldGroup = group;
248-
}
249-
};
250236
private final ChangedListener<Group> groupContentChangedListener = new ChangedListener<Group>() {
251237

252238
@Override
@@ -511,6 +497,7 @@ void setSelectedFigures(List<Figure> list) {
511497
void close() {
512498
filterChain.getChangedEvent().removeListener(filterChainChangedListener);
513499
sequenceFilterChain.getChangedEvent().removeListener(filterChainChangedListener);
500+
getChangedEvent().fire();
514501
}
515502

516503
Iterable<InputGraph> getGraphsForward() {

‎src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorInputGraphProvider.java

+22-6
Original file line numberDiff line numberDiff line change
@@ -37,31 +37,47 @@
3737
@ServiceProvider(service=InputGraphProvider.class)
3838
public class EditorInputGraphProvider implements InputGraphProvider {
3939

40-
private EditorTopComponent editor;
40+
private final EditorTopComponent editor;
4141

42-
public EditorInputGraphProvider() {}
42+
public EditorInputGraphProvider() {
43+
editor = null;
44+
}
4345

4446
public EditorInputGraphProvider(EditorTopComponent editor) {
4547
this.editor = editor;
4648
}
4749

4850
@Override
4951
public InputGraph getGraph() {
50-
return editor.getDiagramModel().getGraphToView();
52+
if (editor != null && editor.isOpened()) {
53+
return editor.getDiagramModel().getGraphToView();
54+
} else {
55+
return null;
56+
}
5157
}
5258

5359
@Override
5460
public void setSelectedNodes(Set<InputNode> nodes) {
55-
editor.setSelectedNodes(nodes);
61+
if (editor != null && editor.isOpened()) {
62+
editor.setSelectedNodes(nodes);
63+
}
5664
}
5765

5866
@Override
5967
public Iterable<InputGraph> searchBackward() {
60-
return editor.getDiagramModel().getGraphsBackward();
68+
if (editor != null && editor.isOpened()) {
69+
return editor.getDiagramModel().getGraphsBackward();
70+
} else {
71+
return null;
72+
}
6173
}
6274

6375
@Override
6476
public Iterable<InputGraph> searchForward() {
65-
return editor.getDiagramModel().getGraphsForward();
77+
if (editor != null && editor.isOpened()) {
78+
return editor.getDiagramModel().getGraphsForward();
79+
} else {
80+
return null;
81+
}
6682
}
6783
}

‎src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java

+15-44
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import com.sun.hotspot.igv.filter.FilterChainProvider;
3838
import com.sun.hotspot.igv.graph.Diagram;
3939
import com.sun.hotspot.igv.graph.Figure;
40-
import com.sun.hotspot.igv.graph.services.DiagramProvider;
4140
import com.sun.hotspot.igv.settings.Settings;
4241
import com.sun.hotspot.igv.util.LookupHistory;
4342
import com.sun.hotspot.igv.util.RangeSlider;
@@ -124,31 +123,8 @@ public void export(File f) {
124123
}
125124
};
126125

127-
private DiagramProvider diagramProvider = new DiagramProvider() {
128-
129-
@Override
130-
public Diagram getDiagram() {
131-
return getModel().getDiagramToView();
132-
}
133-
134-
@Override
135-
public ChangedEvent<DiagramProvider> getChangedEvent() {
136-
return diagramChangedEvent;
137-
}
138-
};
139-
140-
private ChangedEvent<DiagramProvider> diagramChangedEvent = new ChangedEvent<>(diagramProvider);
141-
142-
143-
private void updateDisplayName() {
144-
setDisplayName(getDiagram().getName());
145-
setToolTipText(getDiagram().getGraph().getGroup().getName());
146-
}
147-
148126
public EditorTopComponent(Diagram diagram) {
149-
150127
LookupHistory.init(InputGraphProvider.class);
151-
LookupHistory.init(DiagramProvider.class);
152128
this.setFocusable(true);
153129
FilterChain filterChain = null;
154130
FilterChain sequence = null;
@@ -208,13 +184,16 @@ public EditorTopComponent(Diagram diagram) {
208184

209185
scene = new DiagramScene(actions, actionsWithSelection, rangeSliderModel);
210186
content = new InstanceContent();
211-
graphContent = new InstanceContent();
212-
this.associateLookup(new ProxyLookup(new Lookup[]{scene.getLookup(), new AbstractLookup(graphContent), new AbstractLookup(content)}));
213187
content.add(exportCookie);
214188
content.add(rangeSliderModel);
215-
content.add(diagramProvider);
189+
graphContent = new InstanceContent();
190+
associateLookup(new ProxyLookup(scene.getLookup(), new AbstractLookup(graphContent), new AbstractLookup(content)));
216191

217-
rangeSliderModel.getDiagramChangedEvent().addListener(diagramChangedListener);
192+
rangeSliderModel.getDiagramChangedEvent().addListener(source -> {
193+
setDisplayName(getDiagram().getName());
194+
setToolTipText(getDiagram().getGraph().getGroup().getName());
195+
graphContent.set(Collections.singletonList(new EditorInputGraphProvider(this)), null);
196+
});
218197
rangeSliderModel.selectGraph(diagram.getGraph());
219198
rangeSliderModel.getViewPropertiesChangedEvent().addListener(new ChangedListener<DiagramViewModel>() {
220199
@Override
@@ -383,7 +362,7 @@ public void run() {
383362
rangeSlider.setVisible(false);
384363
}
385364

386-
updateDisplayName();
365+
getModel().getDiagramChangedEvent().fire();
387366
}
388367

389368
public DiagramViewModel getDiagramModel() {
@@ -428,7 +407,11 @@ public FilterChain getFilterChain() {
428407
}
429408

430409
public static EditorTopComponent getActive() {
431-
return (EditorTopComponent) EditorTopComponent.getRegistry().getActivated();
410+
try {
411+
return (EditorTopComponent) EditorTopComponent.getRegistry().getActivated();
412+
} catch (Exception e) {
413+
return null;
414+
}
432415
}
433416

434417
/** This method is called from within the constructor to
@@ -460,6 +443,7 @@ public int getPersistenceType() {
460443
public void componentClosed() {
461444
super.componentClosed();
462445
rangeSliderModel.close();
446+
LookupHistory.terminate(InputGraphProvider.class);
463447
}
464448

465449
@Override
@@ -468,26 +452,13 @@ protected String preferredID() {
468452
}
469453

470454
private void closeOnRemovedOrEmptyGroup() {
471-
Group group = getDiagram().getGraph().getGroup();
455+
Group group = getDiagramModel().getGroup();
472456
if (!group.getParent().getElements().contains(group) ||
473457
group.getGraphs().isEmpty()) {
474458
close();
475459
}
476460
}
477461

478-
private ChangedListener<DiagramViewModel> diagramChangedListener = new ChangedListener<DiagramViewModel>() {
479-
480-
@Override
481-
public void changed(DiagramViewModel source) {
482-
updateDisplayName();
483-
Collection<Object> list = new ArrayList<>();
484-
list.add(new EditorInputGraphProvider(EditorTopComponent.this));
485-
graphContent.set(list, null);
486-
diagramProvider.getChangedEvent().fire();
487-
}
488-
489-
};
490-
491462
public boolean showPredSucc() {
492463
return (Boolean) predSuccAction.getValue(PredSuccAction.STATE);
493464
}

1 commit comments

Comments
 (1)

openjdk-notifier[bot] commented on Sep 21, 2022

@openjdk-notifier[bot]
Please sign in to comment.