Reading this post on Romain Guy’s blog, I decided to write my own reflective container, with support for translucency for the original component and allowing any kind of child components.


Download the (small) demo

The result I have is a pretty straightforward Swing container, which has the following two parameters : global alpha component and size of reflection (fraction of the component’s size).

The main limitation I faced during development is the need of a repaint of the container whenever any of its children content is repainted. For now I register mouse, mouse motion, focus and key listeners in all the content’s sub-components (handling properly the case of components added/removed after the content has been assigned to the reflective container by adding a container listener that keeps the listeners registration state up to date). Hence, when the user types in a textfield, for instance, the reflection follows closely the original. However, it still lacks a hook for spontaneous repaints (hence the blinking caret will not be repainted). I tried writing a proxy RepaintManager, without success so far.

For the rendering logic only one BufferedImage is needed, unlike in the method proposed by Romain Guy : I make the content to draw on the top half of the image. If the alpha set is smaller than one, I draw an alpha mask on it (using AlphaComposite.DstIn). Then I draw the top of the image on the bottom of the same image using a reflection AffineTransform, then I write the alpha mask on the bottom part (still using AlphaComposite.DstIn), and eventually I draw the image on the screen.