Skip to content

Commit 61ae623

Browse files
committed
Added Go to Source action to some views where missing
- Memory Sampler - Memory Truffle Sampler - JFR CPU and Memory Sampler Some other views still TBD: - thread dumps, stack traces - polyglot heap viewer
1 parent 1bae5b2 commit 61ae623

File tree

7 files changed

+234
-11
lines changed

7 files changed

+234
-11
lines changed

visualvm/jfr/src/org/graalvm/visualvm/jfr/views/sampler/Bundle.properties

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
2+
# Copyright (c) 2019, 2020, 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
@@ -229,6 +229,7 @@ MemoryView_TOOLTIP_Col_count=Number of live instances
229229
MemoryView_LBL_Results=Results\:
230230
MemoryView_LBL_Data=Collected data\:
231231
MemoryView_LBL_Snapshot=Snapshot
232+
MemoryView_Context_GoToSource=Go to Source
232233

233234
ThreadsMemoryView_TOOLTIP_Col_name=Thread name
234235
ThreadsMemoryView_TOOLTIP_Col_bytes=Total bytes allocated by thread

visualvm/jfr/src/org/graalvm/visualvm/jfr/views/sampler/CPUSamplerViewSupport.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2020, 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
@@ -52,6 +52,7 @@
5252
import org.graalvm.visualvm.lib.jfluid.client.ClientUtils;
5353
import org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;
5454
import org.graalvm.visualvm.lib.jfluid.results.cpu.StackTraceSnapshotBuilder;
55+
import org.graalvm.visualvm.lib.profiler.api.GoToSource;
5556
import org.graalvm.visualvm.lib.profiler.api.icons.Icons;
5657
import org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;
5758
import org.graalvm.visualvm.lib.ui.cpu.SnapshotCPUView;
@@ -178,8 +179,8 @@ private SnapshotCPUView createView(CPUResultsSnapshot snapshot) {
178179
@Override protected boolean profileMethodEnabled() { return false; }
179180
@Override protected boolean profileMethodSupported() { return false; }
180181
@Override protected boolean profileClassSupported() { return false; }
181-
@Override protected boolean showSourceSupported() { return false; }
182-
@Override protected void showSource(ClientUtils.SourceCodeSelection value) {}
182+
@Override protected boolean showSourceSupported() { return GoToSource.isAvailable(); }
183+
@Override protected void showSource(ClientUtils.SourceCodeSelection value) { GoToSource.openSource(null, value.getClassName(), value.getMethodName(), value.getMethodSignature()); }
183184
@Override protected void selectForProfiling(ClientUtils.SourceCodeSelection value) {}
184185
};
185186
}

visualvm/jfr/src/org/graalvm/visualvm/jfr/views/sampler/MemorySamplerViewSupport.java

+199-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2020, 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
@@ -25,12 +25,25 @@
2525
package org.graalvm.visualvm.jfr.views.sampler;
2626

2727
import java.awt.BorderLayout;
28+
import java.awt.Component;
29+
import java.awt.Container;
30+
import java.awt.Dimension;
2831
import java.awt.Font;
32+
import java.awt.LayoutManager;
33+
import java.awt.event.ActionEvent;
2934
import java.util.HashMap;
3035
import java.util.Map;
36+
import javax.swing.AbstractAction;
37+
import javax.swing.Action;
38+
import javax.swing.ActionMap;
39+
import javax.swing.InputMap;
40+
import javax.swing.JComponent;
41+
import javax.swing.JMenuItem;
3142
import javax.swing.JPanel;
43+
import javax.swing.JPopupMenu;
3244
import javax.swing.SortOrder;
3345
import javax.swing.SwingUtilities;
46+
import javax.swing.UIManager;
3447
import javax.swing.table.AbstractTableModel;
3548
import org.graalvm.visualvm.core.ui.components.DataViewComponent;
3649
import org.graalvm.visualvm.jfr.model.JFREvent;
@@ -40,12 +53,16 @@
4053
import org.graalvm.visualvm.jfr.model.JFRThread;
4154
import org.graalvm.visualvm.jfr.views.components.MessageComponent;
4255
import org.graalvm.visualvm.lib.jfluid.utils.StringUtils;
56+
import org.graalvm.visualvm.lib.profiler.api.ActionsSupport;
57+
import org.graalvm.visualvm.lib.profiler.api.GoToSource;
4358
import org.graalvm.visualvm.lib.profiler.api.icons.Icons;
4459
import org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;
4560
import org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;
4661
import org.graalvm.visualvm.lib.ui.Formatters;
62+
import org.graalvm.visualvm.lib.ui.swing.FilterUtils;
4763
import org.graalvm.visualvm.lib.ui.swing.ProfilerTable;
4864
import org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;
65+
import org.graalvm.visualvm.lib.ui.swing.SearchUtils;
4966
import org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;
5067
import org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;
5168
import org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;
@@ -72,6 +89,10 @@ static final class HeapViewSupport extends JPanel implements JFREventVisitor {
7289
private ProfilerTable table;
7390
private HideableBarRenderer[] renderers;
7491

92+
private JComponent bottomPanel;
93+
private JComponent filterPanel;
94+
private JComponent searchPanel;
95+
7596

7697
HeapViewSupport(JFRModel model) {
7798
hasData = model.containsEvent(JFRSnapshotSamplerViewProvider.ObjectCountChecker.class);
@@ -163,7 +184,31 @@ private void initComponents() {
163184
add(MessageComponent.noData("Heap histogram", JFRSnapshotSamplerViewProvider.ObjectCountChecker.checkedTypes()), BorderLayout.CENTER);
164185
} else {
165186
tableModel = new HeapTableModel();
166-
table = new ProfilerTable(tableModel, true, true, null);
187+
table = new ProfilerTable(tableModel, true, true, null) {
188+
protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {
189+
final String selectedClass = value == null ? null : value.toString();
190+
191+
if (GoToSource.isAvailable()) {
192+
popup.add(new JMenuItem(NbBundle.getMessage(MemorySamplerViewSupport.class, "MemoryView_Context_GoToSource")) { // NOI18N
193+
{ setEnabled(selectedClass != null); setFont(getFont().deriveFont(Font.BOLD)); }
194+
protected void fireActionPerformed(ActionEvent e) { GoToSource.openSource(null, selectedClass, null, null); }
195+
});
196+
popup.addSeparator();
197+
}
198+
199+
popup.add(createCopyMenuItem());
200+
popup.addSeparator();
201+
202+
popup.add(new JMenuItem(FilterUtils.ACTION_FILTER) {
203+
protected void fireActionPerformed(ActionEvent e) { HeapViewSupport.this.activateFilter(); }
204+
});
205+
popup.add(new JMenuItem(SearchUtils.ACTION_FIND) {
206+
protected void fireActionPerformed(ActionEvent e) { HeapViewSupport.this.activateSearch(); }
207+
});
208+
}
209+
};
210+
211+
table.providePopupMenu(true);
167212

168213
table.setMainColumn(0);
169214
table.setFitWidthColumn(0);
@@ -183,7 +228,159 @@ private void initComponents() {
183228
table.setColumnRenderer(2, renderers[1]);
184229

185230
add(new ProfilerTableContainer(table, false, null), BorderLayout.CENTER);
231+
232+
InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
233+
ActionMap actionMap = getActionMap();
234+
235+
final String filterKey = org.graalvm.visualvm.lib.ui.swing.FilterUtils.FILTER_ACTION_KEY;
236+
Action filterAction = new AbstractAction() {
237+
public void actionPerformed(ActionEvent e) {
238+
HeapViewSupport.this.activateFilter();
239+
}
240+
};
241+
ActionsSupport.registerAction(filterKey, filterAction, actionMap, inputMap);
242+
243+
final String findKey = SearchUtils.FIND_ACTION_KEY;
244+
Action findAction = new AbstractAction() {
245+
public void actionPerformed(ActionEvent e) {
246+
HeapViewSupport.this.activateSearch();
247+
}
248+
};
249+
ActionsSupport.registerAction(findKey, findAction, actionMap, inputMap);
250+
251+
SwingUtilities.invokeLater(new Runnable() {
252+
public void run() { SearchUtils.enableSearchActions(table); }
253+
});
254+
}
255+
}
256+
257+
private JComponent getBottomPanel() {
258+
if (bottomPanel == null) {
259+
bottomPanel = new JPanel(new FilterFindLayout());
260+
bottomPanel.setOpaque(true);
261+
bottomPanel.setBackground(UIManager.getColor("controlShadow")); // NOI18N
262+
add(bottomPanel, BorderLayout.SOUTH);
263+
}
264+
return bottomPanel;
265+
}
266+
267+
private void activateFilter() {
268+
JComponent panel = getBottomPanel();
269+
270+
if (filterPanel == null) {
271+
filterPanel = FilterUtils.createFilterPanel(table, null);
272+
panel.add(filterPanel);
273+
Container parent = panel.getParent();
274+
parent.invalidate();
275+
parent.revalidate();
276+
parent.repaint();
277+
}
278+
279+
panel.setVisible(true);
280+
281+
filterPanel.setVisible(true);
282+
filterPanel.requestFocusInWindow();
283+
}
284+
285+
private void activateSearch() {
286+
JComponent panel = getBottomPanel();
287+
288+
if (searchPanel == null) {
289+
searchPanel = SearchUtils.createSearchPanel(table);
290+
panel.add(searchPanel);
291+
Container parent = panel.getParent();
292+
parent.invalidate();
293+
parent.revalidate();
294+
parent.repaint();
295+
}
296+
297+
panel.setVisible(true);
298+
299+
searchPanel.setVisible(true);
300+
searchPanel.requestFocusInWindow();
301+
}
302+
303+
304+
private final class FilterFindLayout implements LayoutManager {
305+
306+
public void addLayoutComponent(String name, Component comp) {}
307+
public void removeLayoutComponent(Component comp) {}
308+
309+
public Dimension preferredLayoutSize(Container parent) {
310+
JComponent filter = filterPanel;
311+
if (filter != null && !filter.isVisible()) filter = null;
312+
313+
JComponent search = searchPanel;
314+
if (search != null && !search.isVisible()) search = null;
315+
316+
Dimension dim = new Dimension();
317+
318+
if (filter != null && search != null) {
319+
Dimension dim1 = filter.getPreferredSize();
320+
Dimension dim2 = search.getPreferredSize();
321+
dim.width = dim1.width + dim2.width + 1;
322+
dim.height = Math.max(dim1.height, dim2.height);
323+
} else if (filter != null) {
324+
dim = filter.getPreferredSize();
325+
} else if (search != null) {
326+
dim = search.getPreferredSize();
327+
}
328+
329+
if ((filter != null || search != null) /*&& hasBottomFilterFindMargin()*/)
330+
dim.height += 1;
331+
332+
return dim;
186333
}
334+
335+
public Dimension minimumLayoutSize(Container parent) {
336+
JComponent filter = filterPanel;
337+
if (filter != null && !filter.isVisible()) filter = null;
338+
339+
JComponent search = searchPanel;
340+
if (search != null && !search.isVisible()) search = null;
341+
342+
Dimension dim = new Dimension();
343+
344+
if (filter != null && search != null) {
345+
Dimension dim1 = filter.getMinimumSize();
346+
Dimension dim2 = search.getMinimumSize();
347+
dim.width = dim1.width + dim2.width + 1;
348+
dim.height = Math.max(dim1.height, dim2.height);
349+
} else if (filter != null) {
350+
dim = filter.getMinimumSize();
351+
} else if (search != null) {
352+
dim = search.getMinimumSize();
353+
}
354+
355+
if ((filter != null || search != null) /*&& hasBottomFilterFindMargin()*/)
356+
dim.height += 1;
357+
358+
return dim;
359+
}
360+
361+
public void layoutContainer(Container parent) {
362+
JComponent filter = filterPanel;
363+
if (filter != null && !filter.isVisible()) filter = null;
364+
365+
JComponent search = searchPanel;
366+
if (search != null && !search.isVisible()) search = null;
367+
368+
int bottomOffset = /* hasBottomFilterFindMargin() ? 1 :*/ 0;
369+
370+
if (filter != null && search != null) {
371+
Dimension size = parent.getSize();
372+
int w = (size.width - 1) / 2;
373+
filter.setBounds(0, 0, w, size.height - bottomOffset);
374+
search.setBounds(w + 1, 0, size.width - w - 1, size.height - bottomOffset);
375+
} else if (filter != null) {
376+
Dimension size = parent.getSize();
377+
filter.setBounds(0, 0, size.width, size.height - bottomOffset);
378+
} else if (search != null) {
379+
Dimension size = parent.getSize();
380+
search.setBounds(0, 0, size.width, size.height - bottomOffset);
381+
}
382+
}
383+
187384
}
188385

189386

visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/memory/Bundle.properties

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ MemoryView_TOOLTIP_Col_count=Number of live instances
6666
MemoryView_LBL_Results=Results\:
6767
MemoryView_LBL_Data=Collected data\:
6868
MemoryView_LBL_Snapshot=Snapshot
69+
MemoryView_Context_GoToSource=Go to Source
6970

7071
MSG_unavailable=Not available.
7172

visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/memory/MemoryView.java

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2020, 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
@@ -34,6 +34,7 @@
3434
import java.awt.Component;
3535
import java.awt.Container;
3636
import java.awt.Dimension;
37+
import java.awt.Font;
3738
import java.awt.LayoutManager;
3839
import java.awt.Toolkit;
3940
import java.awt.event.ActionEvent;
@@ -77,6 +78,7 @@
7778
import org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;
7879
import org.graalvm.visualvm.lib.jfluid.utils.Wildcards;
7980
import org.graalvm.visualvm.lib.profiler.api.ActionsSupport;
81+
import org.graalvm.visualvm.lib.profiler.api.GoToSource;
8082
import org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;
8183
import org.graalvm.visualvm.lib.profiler.api.icons.Icons;
8284
import org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;
@@ -272,7 +274,16 @@ private void initComponents(final Application application) {
272274
table = new ProfilerTable(tableModel, true, true, null) {
273275

274276
protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {
275-
String selectedClass = value == null ? null : value.toString();
277+
final String selectedClass = value == null ? null : value.toString();
278+
279+
if (GoToSource.isAvailable()) {
280+
popup.add(new JMenuItem(NbBundle.getMessage(MemoryView.class, "MemoryView_Context_GoToSource")) { // NOI18N
281+
{ setEnabled(selectedClass != null); setFont(getFont().deriveFont(Font.BOLD)); }
282+
protected void fireActionPerformed(ActionEvent e) { GoToSource.openSource(null, selectedClass, null, null); }
283+
});
284+
popup.addSeparator();
285+
}
286+
276287
if (snapshotDumper != null && selectedClass != null) {
277288
JMenuItem[] customItems = createCustomMenuItems(application, selectedClass);
278289
if (customItems != null) {

visualvm/sampler/src/org/graalvm/visualvm/sampler/memory/Bundle.properties

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
2+
# Copyright (c) 2007, 2020, 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
@@ -86,6 +86,7 @@ MemoryView_TOOLTIP_Col_count=Number of live instances
8686
MemoryView_LBL_Results=Results\:
8787
MemoryView_LBL_Data=Collected data\:
8888
MemoryView_LBL_Snapshot=Snapshot
89+
MemoryView_Context_GoToSource=Go to Source
8990

9091
ThreadsMemoryView_TOOLTIP_Col_name=Thread name
9192
ThreadsMemoryView_TOOLTIP_Col_bytes=Total bytes allocated by thread

visualvm/sampler/src/org/graalvm/visualvm/sampler/memory/MemoryView.java

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2007, 2020, 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
@@ -35,6 +35,7 @@
3535
import java.awt.Component;
3636
import java.awt.Container;
3737
import java.awt.Dimension;
38+
import java.awt.Font;
3839
import java.awt.LayoutManager;
3940
import java.awt.Toolkit;
4041
import java.awt.event.ActionEvent;
@@ -78,6 +79,7 @@
7879
import org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;
7980
import org.graalvm.visualvm.lib.jfluid.utils.Wildcards;
8081
import org.graalvm.visualvm.lib.profiler.api.ActionsSupport;
82+
import org.graalvm.visualvm.lib.profiler.api.GoToSource;
8183
import org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;
8284
import org.graalvm.visualvm.lib.profiler.api.icons.Icons;
8385
import org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;
@@ -286,7 +288,16 @@ private void initComponents(final Application application) {
286288
// return ThreadsMemoryView.this.getUserValueForRow(row);
287289
// }
288290
protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {
289-
String selectedClass = value == null ? null : value.toString();
291+
final String selectedClass = value == null ? null : value.toString();
292+
293+
if (GoToSource.isAvailable()) {
294+
popup.add(new JMenuItem(NbBundle.getMessage(MemoryView.class, "MemoryView_Context_GoToSource")) { // NOI18N
295+
{ setEnabled(selectedClass != null); setFont(getFont().deriveFont(Font.BOLD)); }
296+
protected void fireActionPerformed(ActionEvent e) { GoToSource.openSource(null, selectedClass, null, null); }
297+
});
298+
popup.addSeparator();
299+
}
300+
290301
if (snapshotDumper != null && selectedClass != null) {
291302
JMenuItem[] customItems = createCustomMenuItems(application, selectedClass);
292303
if (customItems != null) {

0 commit comments

Comments
 (0)