
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

/**
 * Demonstrates the problem of the optimizedDrawingEnabled property of a
 * JLayeredPane not be revalidated when the layer of a component changes.
 * This shows how a component on a lower layer can paint on top of a component
 * on an upper layer when it repaints on its own. When the entire layered pane
 * repaints, it paints as normal. Note that if the layer is specified as a
 * constraint when the component is added, it always paints correctly.
 */
public class Main {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame f = new JFrame();
                JLayeredPane layeredPane = f.getLayeredPane();
                layeredPane.setLayout(null);
                
                final JPanel red = new JPanel();
                red.setBackground(Color.RED);
                red.setSize(100, 100);
                red.setLocation(10, 10);
                
                final JPanel blue = new JPanel();
                blue.setBackground(Color.BLUE);
                blue.setSize(100, 100);
                blue.setLocation(60, 60);
                layeredPane.add(red);
                layeredPane.add(blue);
                
                layeredPane.setLayer(red, 200, 0);
                layeredPane.setLayer(blue, 100, 0);
                
                Timer t = new Timer(1000, new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        blue.repaint();
                        System.out.println("repaint");
                    }
                });
                t.start();
                
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setPreferredSize(new Dimension(600, 400));
                f.pack();
                f.setLocationRelativeTo(null);
                f.setVisible(true);
            }
        });
    }
}
