Demos for Layered Panes

The source code, demos and examples for the chapter 10 of Filthy Rich Clients are available online. This chapter presents layered panes.

The next batch of demos, focusing on Repaint Manager, will contain my favorite demo, a real-time reflection applied on a QuickTime movie.

12 Responses to “Demos for Layered Panes”

  1. Java Crazy says:

    The examples are very useful but i’d like to point out an error- the glasspane examples- the intercept events example consists of the same example as in glass pane painting

  2. Romain Guy says:

    Nope. The examples look the same but they are different and the book explains why…

  3. Java Crazy says:

    ok! well thanks!

  4. Antonis says:

    The StackLayoutDemo is impressive. I do have a question though. How does your custom StackLayout layout manager differ from the supplied (in 1.6) OverlayLayout ? I noticed I could easily convert the example to use OverlayLayout. Any particular reason for the custom layout manager ?

  5. Romain Guy says:

    OverlayLayout is included in Java SE since J2SE 1.3. If I remember correctly, OverlayLayout does not size the components in the same manner as StackLayout does. StackLayout make sure that all the children take up all of the available space, which is not the case in OverlayLayout.

  6. Antonis says:

    I see ! Thanks Romain. I have another question if I may. It has be bugging me for quite some time now and I think if someone can help that must be you. It is, however, a bit more involved. I wonder if we could take it in private and if you later decide it maybe of general interest you may post it. It boils down to this: I have run into a situation where in order for my custom component to be painted correctly I have to turn off double-buffering on the RepaintManager !!! Interesting, isn’t it ?

  7. Chet Haase says:

    Antonis: I don’t know why this would be the case off-hand; some sample code (tiny test case) would help. There are sometimes issues with rendering Swing components to images that require disabling double-buffering, but I don’t know of issues when doing normal rendering to the Swing frame.

  8. About the double-buffering. I found that for some components you have to turn it off if you want to render that component to an arbitrary Graphics (for example, if you want to paint that component to an image and save the image as a file). I know that the usual (double buffering enabled) doesn’t work correctly on (at least) internal frames, viewports and dialogs.

  9. Antonis says:

    Chet, Kirill, that’s exactly my case ! .
    ( I only hope you don’t get discouraged by the long post and read on).

    I have implemented a component that imitates the translucency of the non-client part of Vista windows. A similar effect has been showcased by Romain (I think it was for the Extreme GUI makeover of 2006). Since I wanted my component to be used in a non-modal way I took a slightly different approach than Romain. Romain took a single snapshot of the hosting JFrame’s contents at initial display of his component. He then blurred the image, applied a color mixing filter and used this as the background of his custom component (which he installed in the layer pane if I recall correctly).
    My component is designed to be installed in the glass pane (so it gets repainted every time something underneath it is changed) and does pretty much the same stuff but for every repaint request that reaches it. It thus, appears completely dynamic in the sense no matter what happens underneath it (the user dragging a table scrollbar or a QuickTime movie playing) it shows through albeit blurred and color-mixed as it should. There are,of course, lots of details like honoring the clipping rectangle, optimizing the expensive blur etc. but at the bottom of it in my paintComponent() I have at some point to draw the dirty part of the content pane on an image that is later processed before it becomes my component’s background.
    Now the interesting part is that in most cases this approach works just fine. However, there are some cases (unfortunately I have not yet been able to nail down the exact characteristics of them) where this approach fails giving inexplicable garbage on the top-left corner of the hosting JFrame (regardless of the position of my component).
    Kirill seems to have a point. Although I never use JInternalFrames or dialogs a viewport is almost always involved in these trouble cases. Furthermore, the viewport clients in all these cases are custom components (which however work perfectly if this translucent component is not used in the same JFrame).

    Temporarily turning off the double buffering just before the call to the contents pane’s paint() method and turning it back on shortly after is just one workaround I have found. Another one is (and this is also very interesting) to replace contentPane.paint(g2) with contentPane.print(g2) !!! This however has a small drawback since for some standard Swing components print() does not paint selections or focus indicators.

    Chet, are these issues you mentioned filed in bug parade ? If they are I would appreciate if you could send me the issue numbers so that I can read more about them.

  10. Romain Guy says:

    Antonis, I have run into this problem and the fix was simple albeit a bit subtle. But for the life of me, I cannot remember what it was. I wonder if you could get away with a clever RepaintManager instead.

  11. Antonis says:

    to be honest, I have never implemented a custom RepaintManager so I do not know enough details (but wait till I get my hands on your book !!!). What I tried to do during implementation of this was to get the RepaintManager’s offscreen buffer in my paintComponent() and use this for blurring and mixing. After all, the paint request reaches the glass pane only after everything else on the root pane is painted (presumably on the offscreen buffer) so performance-wise it makes a lot of sense to use this already prepared image instead for asking for yet another repaint on another image. However, I could not make this work no matter what and the reason is still a mystery.
    Just out of curiosity can you remember if your fix involved temporarily resizing your component to zero width and height ?
    (an earlier encounter with a similar problem required this trick).

  12. Antonis says:

    ‘…I have run into this problem and the fix was simple…I cannot remember what it was…’

    Which reminds me of Fermat !

    You French guys are just incredible :-)