Using VisualVM, BTrace & Good Old Web Search
You can think of btrace as a scriptable debugger: you set breakpoints and when your breakpoints are hit some little script gets executed.
First, I wanted to see the animator calls. Those were on the actionPerformed method, resulting in this annotation for a btrace method:
I also needed the object itself, so I used the @Self annotation to get it from btrace:
public static void lnfaction(@Self Object animator)
Now, from the heap dump analysis above I knew that I had a reference to the progress bar here, so I used a bit of reflection to get to it:
println( strcat(strcat(str(timeNanos()), " : animator called "),str(animator)));
Field f = field("apple.laf.CUIAquaProgressBar$Animator", "this$0");
/*apple.laf.CUIAquaProgressBar*/ Object pbar = get(f,animator);
Field f2 = field("apple.laf.CUIAquaProgressBar", "progressBar");
/*org.netbeans.modules.progress.ui.NbProgressBar*/ Object swingbar = get(f2, pbar);
Note how limited you are while writing the script... no method calls are actually allowed except those from com.sun.btrace.BTraceUtils (which are statically imported). Even string concatenation has to be explicit, using BTraceUtils.strcat! Yet, it gives you enough options to progress quite nicely.
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)