The Source for Java Technology Collaboration
User: Password:



Scott Violet

Scott Violet's Blog

Modern Heap View

Posted by zixle on June 19, 2006 at 06:25 AM | Comments (16)

As part of brain storming on future ideas one of the visual designers did a mockup of NetBeans that included a more modern looking heap view. I was rather taken by it and decided to do an implementation, hence this blog. I had to cut a few corners, and features, to avoid the view consuming too much memory. As usual, for those that don't have the stomach to wade through a blog the following shows the heap view in action.

Source can be found here.

For those using NetBeans 5.0 I've created a module with this heap view in it. The module is here. To install this in NetBeans click on Tools -> Module Manager, then click on the 'Update' button, choose the 'Install Manually Downloaded Modules' and follow the instructions. Here's the source for the module.

Dissecting the View

The view consists of the following:
Small Border
A background gradient.
A grid with each cell having a slight gradient.
Vertical lines representing the amount of the heap being used at a particular time. The ticks are also drawn with a gradient.
A grid on top of the ticks.
Textual description showing amount of heap being used, with a drop shadow.
Yes, gradients galore;)

You can toggle a couple of options by right clicking.

Gradients

The code for rendering a gradient is pretty simple, pick the end points, colors, invoke setPaint, and fill in the region:
  Paint gradient = new GradientPaint(0, 0, color1, width, height, color2);
  g2.setPaint(gradient);
  g2.fillRect(0, 0, width, height);
It's worth mentioning a couple of new gradients have recently been added to 1.6. I wanted this code to work with 1.4.2, so I restricted myself to GradientPaint. For details on the new gradient classes look to Chris's blog.

The vitues of caching

A good heap view shouldn't accumulate much garbage on any given paint, otherwise when the heap view is running you'll be able to watch the amount of garbage continually grow and shrink even when you're not doing anything. Believe me, my first implementations did this and it wasn't pretty;) To avoid the garbage I ended up creating a bunch of images and doing image copies from the images. Turns out this generates very little garbage and is much faster; all around goodness.

If you look at the source you'll see a number of images. There is one for the border, background gradient and tiles, another for the tick gradient, and two for the text (I'll get to that in second).

The drop shadow

If you look closely at the text you can see a slight drop shadow. To create a drop shadow requires a bit of the more obscure 2D operations. The general algorithm is:
  1. Render what ever it is you want to create the drop shadow of to an image.
  2. Render that image to another image using a BufferedImageOp.
  3. Rerender step 1 to the second image.
Here's what this looks like in terms of creating a drop shadow for text.
  BufferedImage textImage = ... ;
  BufferedImage dropShadowImage = ...;

  // Step 1:
  Graphics2D textImageG = textImage.createGraphics();
  textImageG.drawString(...);
  textImageG.dispose();

  // Step 2:
  Graphics2D dropShadowG = dropShadowImage.createGraphics();
  dropShadowG.drawImage(textImage, bufferedImageOp, shiftX, shiftY);

  // Step 3:
  drawShadowG.drawString(...);
  drawShadowG.dispose();
So, what is bufferedImageOp? For a drop shadow effect it's a ConvolveOp. Here's the code:
  int kw = KERNEL_SIZE, kh = KERNEL_SIZE;
  float blurFactor = BLUR_FACTOR;
  float[] kernelData = new float[kw * kh];
  for (int i = 0; i < kernelData.length; i++) {
    kernelData[i] = blurFactor;
  }
  bufferedImageOp = new ConvolveOp(new Kernel(kw, kh, kernelData));
As I said, a bit obscure. You can play with the KERNEL_SIZE and BLUR_FACTORY to get different effects, I've used 3 and .1 respectively.

As part of this years Extreme GUI talk I wrote an app that lets you interactively experiment with these values and see the effects. I'll blog on that later. I know, I know, what about the architecture series? I will return to it! And yes, this years extreme GUI code will be released. And yes, I've been a bad BAD boy! Bad Scott, bad Scott!

Sorry, back to this blog.

Variations

I experimented with a handful of variations until I arrived at this one. You can try a couple of them by right clicking on the heap view and choosing one of the options. And just as with the heap view in NetBeans, a single click triggers a GC (I didn't add the flashing effect, sorry).

I suspect I could have spent weeks fine tuning (I'm aware of at least one other optimization I could have done), adding more features, refining the look, more effects (yes, there is one effect buried in the implementation and I played with more) ... But, I figured it best to push out what's there and move on to the next thing.

So, that's it. What do you think?

    -Scott


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • It looks great on MacOS X with the antialiased text that you left off your screenshot, antialiasing hater that you are :p

    Posted by: gfx on June 19, 2006 at 06:39 AM

  • It looks great on MacOS X with the antialiased text that you left off your screenshot, antialiasing hater that you are :p BTW, the source code link yields to a 404 error.

    Posted by: gfx on June 19, 2006 at 06:41 AM

  • Looks great. Especially the smooth transition when the heap size changes is very slick.
    I wanted to browse the source code, but it's giving me a 404.
    Also there's a tiny typo in the jnlp file. When launching it says 'Moder Heap View Test' (missing n).

    Posted by: pepijnve on June 19, 2006 at 07:05 AM

  • It does look great but it hurt my eyes. Those colors are hard to see, including fancy fade effect on the left.

    Posted by: euxx on June 19, 2006 at 07:51 AM

  • the source code link yields to a 404 error.

    java.net seems to be flakey with uploads lately. It took me about 5 times to get each file to stick. Try again, hopefully it'll work now.

       -Scott

    Posted by: zixle on June 19, 2006 at 08:01 AM

  • antialiasing hater that you are

    You know me too well Romain;)

        -Scott

    Posted by: zixle on June 19, 2006 at 08:01 AM

  • I dig it! Just 2 things though...when are you giving the 5.5 daily builds some GC UI lovin....and also how much more memory does this take than the drab old Netbeans version of the GC? See, I would rather Netbeans take up more memory but look very flash...I remember a blog post with quite a few posts saying how Netbeans looks quite boring and unprofessional. Maybe we should let you and Romain and Josh full reign on all that you can do to make Netbeans all fancy shmancy!

    Posted by: suryad on June 19, 2006 at 10:18 AM

  • nice, I wish I had time to fancy up my apps like that.

    Posted by: francisdb on June 19, 2006 at 01:01 PM

  • Given the sohpistication of the effects (which are great), it does seem a little small (and khaki!) to really appreciate it properly

    - Danny

    Posted by: dannyc on June 19, 2006 at 05:40 PM

  • I really like it too.

    Posted by: elendal on June 19, 2006 at 07:26 PM

  • Hey Scott, your text centering code doesn't seem to be correct: on my system with non-default DPI the text is not centered..

    Dmitri

    Posted by: trembovetski on June 21, 2006 at 12:48 AM

  • Or may be it is supposed to be like that?

    Posted by: trembovetski on June 21, 2006 at 12:49 AM

  • your text centering code doesn't seem to be correct:

    The algorithm is a bit odd. I calculate the width of the biggest I'll let the text get, then right align in that space. At least that's what I think I'm doing. Have to look at the code again to be sure.

        -Scott

    Posted by: zixle on June 21, 2006 at 07:01 AM

  • I like it. I will add it to a vorkin application. I will add mouse listener to listent to mouse clicks in order to call System.gc(). I will try to change the gradient (revers it) when mouse is clicked on the heap view, in order to simulate button presure.

    Posted by: crosati on June 21, 2006 at 07:40 AM


  • cute :-) and ready to use in SwingX JXStatusbar:

    private JXFrame buildFrame() {
    JXFrame frame = new JXFrame("Show Scott's HeapView in SwingX");
    HeapView heapView = new HeapView();
    JXStatusBar statusBar = new JXStatusBar();
    statusBar.add(heapView);
    frame.getRootPaneExt().setStatusBar(statusBar);
    return frame;
    }


    Posted by: kleopatra on June 26, 2006 at 07:13 AM

  • Oh yes - this one is great.

    Posted by: shake on July 01, 2006 at 05:01 PM



Only logged in users may post comments. Login Here.


Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds