24
24
*/
25
25
package org .graalvm .visualvm .heapviewer .truffle ;
26
26
27
+ import java .awt .BorderLayout ;
28
+ import java .awt .GridBagConstraints ;
29
+ import java .awt .GridBagLayout ;
30
+ import java .awt .Insets ;
27
31
import java .awt .event .ActionEvent ;
28
32
import java .util .List ;
29
33
import java .util .Objects ;
42
46
import org .graalvm .visualvm .heapviewer .ui .TreeTableView ;
43
47
import org .graalvm .visualvm .heapviewer .ui .TreeTableViewColumn ;
44
48
import javax .swing .Icon ;
49
+ import javax .swing .JButton ;
45
50
import javax .swing .JCheckBoxMenuItem ;
51
+ import javax .swing .JPanel ;
46
52
import javax .swing .JPopupMenu ;
47
53
import javax .swing .SwingUtilities ;
54
+ import org .graalvm .visualvm .heapviewer .truffle .swing .LinkButton ;
55
+ import org .graalvm .visualvm .lib .ui .UIUtils ;
48
56
import org .openide .util .NbBundle ;
49
57
import org .openide .util .NbPreferences ;
50
58
54
62
*/
55
63
@ NbBundle .Messages ({
56
64
"TruffleObjectPropertyPlugin_NoSelection=<no object selected>" ,
65
+ "TruffleObjectPropertyPlugin_NoSelectionEx=<no object or type selected>" ,
57
66
"TruffleObjectPropertyPlugin_NoItems=<no {0}>" , // <no items>
58
- "TruffleObjectPropertyPlugin_ShowMergedSwitch=Show merged {0}"
67
+ "TruffleObjectPropertyPlugin_AutoShowMergedSwitch=Compute merged {0} automatically" ,
68
+ "TruffleObjectPropertyPlugin_ComputeMergedReferencesLbl=Compute Merged {0}" ,
69
+ "TruffleObjectPropertyPlugin_ComputeMergedReferencesTtp=Compute merged {0} for the selected type" ,
70
+ "TruffleObjectPropertyPlugin_AutoComputeMergedReferencesLbl=Compute Merged {0} Automatically" ,
71
+ "TruffleObjectPropertyPlugin_AutoComputeMergedReferencesTtp=Compute merged {0} automatically for each selected type"
59
72
})
60
73
public class TruffleObjectPropertyPlugin <O extends TruffleObject , T extends TruffleType <O >, F extends TruffleLanguageHeapFragment <O , T >, L extends TruffleLanguage <O , T , F >> extends HeapViewPlugin {
61
74
62
- private static final String KEY_TYPE_PROPERTIES_HISTOGRAM = "tPropertiesHisto" ; // NOI18N
63
-
64
- private volatile boolean tPropertiesHisto = readItem (KEY_TYPE_PROPERTIES_HISTOGRAM , true );
65
-
66
75
private static final TreeTableView .ColumnConfiguration CCONF_TYPE = new TreeTableView .ColumnConfiguration (DataType .COUNT , null , DataType .COUNT , SortOrder .DESCENDING , Boolean .FALSE );
67
76
private static final TreeTableView .ColumnConfiguration CCONF_OBJECT = new TreeTableView .ColumnConfiguration (null , DataType .COUNT , DataType .NAME , SortOrder .UNSORTED , null );
68
77
@@ -72,6 +81,8 @@ public class TruffleObjectPropertyPlugin<O extends TruffleObject, T extends Truf
72
81
73
82
private HeapViewerNode selected ;
74
83
84
+ private volatile boolean mergedRequest ;
85
+
75
86
private final TreeTableView objectsView ;
76
87
77
88
@@ -80,34 +91,45 @@ public TruffleObjectPropertyPlugin(String name, String description, Icon icon, S
80
91
81
92
this .provider = provider ;
82
93
83
- if (! provider . supportsAggregation ()) tPropertiesHisto = false ;
94
+ final String mergedPropertiesKey = provider . getMergedPropertiesKey () ;
84
95
85
96
heap = context .getFragment ().getHeap ();
86
97
87
- TreeTableViewColumn [] columns = provider . supportsAggregation () ?
98
+ TreeTableViewColumn [] columns = mergedPropertiesKey == null ?
88
99
new TreeTableViewColumn [] {
89
100
new TreeTableViewColumn .Name (heap ),
90
101
new TreeTableViewColumn .LogicalValue (heap ),
91
- new TreeTableViewColumn .Count (heap , true , true ),
92
102
new TreeTableViewColumn .OwnSize (heap , false , false ),
93
103
new TreeTableViewColumn .RetainedSize (heap , false , false ),
94
104
new TreeTableViewColumn .ObjectID (heap )
95
105
} : new TreeTableViewColumn [] {
96
106
new TreeTableViewColumn .Name (heap ),
97
107
new TreeTableViewColumn .LogicalValue (heap ),
108
+ new TreeTableViewColumn .Count (heap , true , true ),
98
109
new TreeTableViewColumn .OwnSize (heap , false , false ),
99
110
new TreeTableViewColumn .RetainedSize (heap , false , false ),
100
111
new TreeTableViewColumn .ObjectID (heap )
101
112
};
102
113
objectsView = new TreeTableView (viewID , context , actions , columns ) {
103
114
protected HeapViewerNode [] computeData (RootNode root , Heap heap , String viewID , HeapViewerNodeFilter viewFilter , List <DataType > dataTypes , List <SortOrder > sortOrders , Progress progress ) throws InterruptedException {
115
+ if (mergedRequest ) return HeapViewerNode .NO_NODES ;
116
+
104
117
HeapViewerNode _selected ;
105
118
synchronized (objectsView ) { _selected = selected ; }
106
119
107
- if (_selected == null ) return new HeapViewerNode [] { new TextNode (Bundle .TruffleObjectPropertyPlugin_NoSelection ()) };
120
+ if (_selected == null ) {
121
+ SwingUtilities .invokeLater (new Runnable () {
122
+ public void run () {
123
+ if (!CCONF_OBJECT .equals (objectsView .getCurrentColumnConfiguration ()))
124
+ objectsView .configureColumns (CCONF_OBJECT );
125
+ }
126
+ });
127
+
128
+ return new HeapViewerNode [] { new TextNode (noSelectionString ()) };
129
+ }
108
130
109
131
HeapViewerNode [] nodes ;
110
- TruffleObjectsWrapper wrapper = ! tPropertiesHisto ? null : HeapViewerNode .getValue (_selected , TruffleObjectsWrapper .DATA_TYPE , heap );
132
+ TruffleObjectsWrapper wrapper = mergedPropertiesKey == null ? null : HeapViewerNode .getValue (_selected , TruffleObjectsWrapper .DATA_TYPE , heap );
111
133
if (wrapper != null ) {
112
134
nodes = provider .getNodes (wrapper , _selected , heap , viewID , viewFilter , dataTypes , sortOrders , progress );
113
135
SwingUtilities .invokeLater (new Runnable () {
@@ -119,7 +141,7 @@ public void run() {
119
141
} else {
120
142
O selectedO = provider .getObject (_selected , heap );
121
143
if (selectedO != null ) nodes = provider .getNodes (selectedO , root , heap , viewID , viewFilter , dataTypes , sortOrders , progress );
122
- else nodes = new HeapViewerNode [] { new TextNode (Bundle . TruffleObjectPropertyPlugin_NoSelection ()) };
144
+ else nodes = new HeapViewerNode [] { new TextNode (noSelectionString ()) };
123
145
SwingUtilities .invokeLater (new Runnable () {
124
146
public void run () {
125
147
if (!CCONF_OBJECT .equals (objectsView .getCurrentColumnConfiguration ()))
@@ -132,29 +154,114 @@ public void run() {
132
154
}
133
155
@ Override
134
156
protected void populatePopup (HeapViewerNode node , JPopupMenu popup ) {
135
- if (! provider .supportsAggregation () ) return ;
157
+ if (provider .getMergedPropertiesKey () == null ) return ;
136
158
137
159
if (popup .getComponentCount () > 0 ) popup .addSeparator ();
138
160
139
- popup .add (new JCheckBoxMenuItem (Bundle .TruffleObjectPropertyPlugin_ShowMergedSwitch (provider .getName ()), tPropertiesHisto ) {
161
+ popup .add (new JCheckBoxMenuItem (Bundle .TruffleObjectPropertyPlugin_AutoShowMergedSwitch (provider .getName ()), isAutoMerge () ) {
140
162
@ Override
141
163
protected void fireActionPerformed (ActionEvent event ) {
142
164
SwingUtilities .invokeLater (new Runnable () {
143
165
@ Override
144
166
public void run () {
145
- tPropertiesHisto = isSelected ();
146
- storeItem (KEY_TYPE_PROPERTIES_HISTOGRAM , tPropertiesHisto );
147
- reloadView ();
167
+ setAutoMerge (isSelected ());
148
168
}
149
169
});
150
170
}
151
171
});
152
172
}
153
173
};
154
174
}
175
+
176
+ private String noSelectionString () {
177
+ return provider .getMergedPropertiesKey () == null ? Bundle .TruffleObjectPropertyPlugin_NoSelection () :
178
+ Bundle .TruffleObjectPropertyPlugin_NoSelectionEx ();
179
+ }
180
+
181
+ private JComponent component ;
182
+
183
+ private void showObjectsView () {
184
+ JComponent c = objectsView .getComponent ();
185
+ if (c .isVisible ()) return ;
186
+
187
+ c .setVisible (true );
188
+
189
+ component .removeAll ();
190
+ component .add (c , BorderLayout .CENTER );
191
+
192
+ mergedRequest = false ;
193
+
194
+ component .invalidate ();
195
+ component .revalidate ();
196
+ component .repaint ();
197
+ }
198
+
199
+ private void showMergedView () {
200
+ JComponent c = objectsView .getComponent ();
201
+ if (!c .isVisible ()) return ;
202
+
203
+ c .setVisible (false );
204
+
205
+ component .removeAll ();
206
+
207
+ String name = provider .getName ();
208
+ String _name = name .substring (0 , 1 ).toUpperCase () + name .substring (1 );
209
+
210
+ JButton jb = new JButton (Bundle .TruffleObjectPropertyPlugin_ComputeMergedReferencesLbl (_name ), getIcon ()) {
211
+ protected void fireActionPerformed (ActionEvent e ) {
212
+ showObjectsView ();
213
+ objectsView .reloadView ();
214
+ }
215
+ };
216
+ jb .setIconTextGap (jb .getIconTextGap () + 2 );
217
+ jb .setToolTipText (Bundle .TruffleObjectPropertyPlugin_ComputeMergedReferencesTtp (name ));
218
+ Insets margin = jb .getMargin ();
219
+ if (margin != null ) jb .setMargin (new Insets (margin .top + 3 , margin .left + 3 , margin .bottom + 3 , margin .right + 3 ));
220
+
221
+
222
+ LinkButton lb = new LinkButton (Bundle .TruffleObjectPropertyPlugin_AutoComputeMergedReferencesLbl (_name )) {
223
+ protected void fireActionPerformed (ActionEvent e ) {
224
+ setAutoMerge (true );
225
+ showObjectsView ();
226
+ objectsView .reloadView ();
227
+ }
228
+ };
229
+ lb .setToolTipText (Bundle .TruffleObjectPropertyPlugin_AutoComputeMergedReferencesTtp (name ));
230
+
231
+
232
+ JPanel p = new JPanel (new GridBagLayout ());
233
+ p .setOpaque (false );
234
+ GridBagConstraints g ;
235
+
236
+ g = new GridBagConstraints ();
237
+ g .fill = GridBagConstraints .HORIZONTAL ;
238
+ g .gridy = 0 ;
239
+ p .add (jb , g );
240
+
241
+ g = new GridBagConstraints ();
242
+ g .fill = GridBagConstraints .HORIZONTAL ;
243
+ g .gridy = 1 ;
244
+ g .insets = new Insets (10 , 0 , 0 , 0 );
245
+ p .add (lb , g );
246
+
247
+ component .add (p );
248
+
249
+ mergedRequest = true ;
250
+
251
+ component .invalidate ();
252
+ component .revalidate ();
253
+ component .repaint ();
254
+ }
155
255
156
256
protected JComponent createComponent () {
157
- return objectsView .getComponent ();
257
+ component = new JPanel (new BorderLayout ());
258
+ component .setOpaque (true );
259
+ component .setBackground (UIUtils .getProfilerResultsBackground ());
260
+
261
+ objectsView .getComponent ().setVisible (false ); // force init in showObjectsView()
262
+ showObjectsView ();
263
+
264
+ return component ;
158
265
}
159
266
160
267
@@ -164,28 +271,25 @@ protected void closed() {
164
271
}
165
272
166
273
167
- protected final boolean supportsAggregation () {
168
- return provider .supportsAggregation ();
169
- }
170
-
171
-
172
274
protected void nodeSelected (HeapViewerNode node , boolean adjusting ) {
173
275
synchronized (objectsView ) {
174
276
if (Objects .equals (selected , node )) return ;
175
-
176
277
selected = node ;
177
278
}
178
279
280
+ if (selected != null && provider .getMergedPropertiesKey () != null && !isAutoMerge () && HeapViewerNode .getValue (selected , TruffleObjectsWrapper .DATA_TYPE , heap ) != null ) showMergedView ();
281
+ else showObjectsView ();
282
+
179
283
objectsView .reloadView ();
180
284
}
181
285
182
286
183
- private static boolean readItem ( String itemName , boolean initial ) {
184
- return NbPreferences .forModule ( TruffleObjectPropertyPlugin . class ).getBoolean ("TruffleObjectPropertyPlugin." + itemName , initial ); // NOI18N
287
+ private boolean isAutoMerge ( ) {
288
+ return NbPreferences .root ( ).getBoolean (provider . getMergedPropertiesKey (), false );
185
289
}
186
290
187
- private static void storeItem ( String itemName , boolean value ) {
188
- NbPreferences .forModule ( TruffleObjectPropertyPlugin . class ).putBoolean ("TruffleObjectPropertyPlugin." + itemName , value ); // NOI18N
291
+ private void setAutoMerge ( boolean value ) {
292
+ NbPreferences .root ( ).putBoolean (provider . getMergedPropertiesKey () , value );
189
293
}
190
294
191
295
}
0 commit comments