I'm puzzled by JLayeredPane. It seems I can't change the layer of component after it's been added to the layered pane and still get proper repainting behaviour (except for JInternalFrames, because there's a special case hack for those). The reason is that if I call setLayer(), it doesn't revalidate the "optimizedDrawingEnabled" property. It remains true even though there are now components on different layers, so a component on layer 0 can paint on top of a component on layer 1. I've attached a simple test case that demonstrates the problem.
Now, I was going to say that's a bug with an easy fix (call validateOptimizedDrawing() in setLayer()), except that the JavaDoc for setLayer(c, layer) says "Should be called before adding to parent". I don't any justification for this limitation. It's a little odd, since setLayer(c, layer) just calls straight in to setLayer(c, layer, position), whose JavaDoc says nothing about when it should or should not be called, so one would assume it should be safe to call it at any time and still have things paint correctly. Surely this must be the case, since why would the method take a position, if it's only meant to be called before the component is added! A component doesn't even have a position until it's added! But no, calling it will not affect optimizedDrawingEnabled, so things will start painting incorrectly. I'd like to remove that line from the JavaDoc, and validate the optimizedDrawingEnabled property whenever the layer of a component in the layered pane changes, so that things always paint properly. I see two ways of doing this: The simplest is to simple call validateOptimizedDrawing() at the end of setLayer(c, layer, position). This is the only possible way for AWT Components. The way I'd probably prefer, atleast for JComponents, is to add a listener for any changes to the LAYER_PROPERTY client property, for any JComponents in the layered pane, and revalidate optimizedDrawingEnabled whenever there's a change. The only downside to this is that there's a static method putLayer() that sets this property, but specifies in the JavaDoc that the method does not cause any side effects, including repainting. But I don't see why you'd want that. Thoughts? PS: It might be useful for any subclasses to make validateOptimizedDrawing() protected. PPS: validateOptimizedDrawing()'s criteria for disabling optimized drawing is whenever any JInternalFrames or added, or if a component is found whose layer is not FRAME_CONTENT_LAYER. Perhaps this could be simplified to disabling whenever there are components on more than one layer.
Main.java
Description: Main.java
