|
|
||
Alexander Potochkin's BlogNovember 2007 ArchivesMaking Rainbow: Spotlight effect and soft clippingPosted by alexfromsun on November 29, 2007 at 11:32 AM | Permalink | Comments (6)Few weeks ago I submitted a session for the next JavaOne and it reminded me the previous session which we presented with Kirill Before J1, he published a nice teaser with links to blogs about his famous ghost effects and transition layout, so it's hight time for me drop a few lines about implementing a spotLight effect. You can test the whole application on the main page of the Rainbow project, here is a flash demo which I made specially for this blog (press the green button on the bottom left side)
ForegroundPainterSpotlightPainter has a layered structure: the scrollPane's view component and the tranclucent foreground with the "holes" for matched components. I divide the painting code between two painters - SpotLightPainter extends DefaultPainter, so the wrapped component is automatically painted when you call super.paint(g2, l), the foregroundPainter is responsible for painting the tranclucent foreground:
The foregroundPainter extends AbstractBufferedPainter which means it is painted via the intermediate image, this is the best solution when it comes to translucency. I fill the whole area with the translucent color and then clip out the shapes over the matched components:
The important thing that by default, AbstractBufferedPainter.isIncrementalUpdate() returns false, it means that this painter will be updated only if the whole JXLayer is repainted, e.g. when the frame is resized or when SpotLightPainter.fireLayerItemChanged() is called. This optimization allows reusing the foreground image for faster painting, it doesn't slow down the transition effect animation because when you move the mouse over a button, foregroundPainter paints the cached image.
Soft clippingWhen we prepared our session, Kirill drew my attention to the fact that spotlights didn't look smooth, here the zoomed out screenshot which shows how it looked like:as the result it was possible to see the jaggies on the spotlight's borders and that made this effect look unprofessional. The remedy for this problem is called "soft clipping" and the pefect article by Chris Cambell is the first thing that came to my mind when I thought about that. The trick from Chris produces the very good result but it works for fixed shapes only, I mean you should know the exact shape in advance to create a mask for it. I decided to find a way how to make soft clipping for arbitrary shapes and I actually found it, but...
a few minutes ago I came across the next Chris's blog Light and Shadow (I missed it for some reason) where he described exactly what I thought was invented by me! :-) The idea is to mix in the alpha value to the pixels on the shape's border by drawing the same shape with a set BasicStroke. For the Rainbow project I painted it once with the 50% alpha and doubled basicStroke width. For the JXLayer's demo I updated SpotLightPainter to be able to set the custom width for the soft clipping, and make it as smooth as you want:
MouseEvents filteringComponents which are outside the spotlights shouldn't react on the mouse events and this was the simplest task for the SpotLightPainter
ConclusionTo add this functionality to your application you just need to wrap you component with JXLayer:
All source and binary files you can find on the SwingHelper project site
Debug Swing repaintingPosted by alexfromsun on November 06, 2007 at 11:22 AM | Permalink | Comments (9)As everybody knows if you need to repaint a Swing component you should call Component.repaint() method, another well-known tip for the fast painting is: If only part of your component needs to be updated, make paint requests using a version of repaint that specifies the painting region. It is very simple piece of advice - not to paint more than you need, but sometimes this situation is not easy to catch. Usually it is obvious when you paint less than you need, but repainting something which hasn't been changed is a kind of "invisible" operation. If the whole frame is repainted when any of its children is repainted you would hardly notice it on modern computer and that is the reason why I decided to return to my old love, Swing debugging and add one debugging tool to JXLayer project A visual indication for repainting events must work for every component, no matter which color it is painted, so I created an elegant layer's UI delegate which catches repainting and shows fade-out effect using inverted colors for a repainted area. With this painter you can study your GUI and eliminate unnecessary painting, moreover it is very interesting just to see how Swing paints the core components - what part of a JTree is repainted when you open a node? What is repainted when you open a popup ? Now it easy to get answers for this kind of questions.
For example, it is easy to see what part of JTextField is repainted when you type in it and what happens when JTree's selection
is changed.I was also very pleased to check that we don't paint more than we need when selection of JTable is changed (second tab in the demo)
I hope you'll find it useful for painting optimization for your custom components and LookAndFeels.
A flash presentation is available, press the green button below to start: alexp | ||
|
|