JLayeredPane y pintura

Estoy escribiendo una aplicación que tiene un JLayeredPane (llámalo capas) que contiene dos JPanels en capas diferentes. Anulo el método paintComponent del JPanel en la parte inferior (llámalo grid_panel) para que dibuje una grilla, y el método paintComponent del que está en la parte superior (llámalo circuit_panel) para que dibuje un circuito.

Aquí hay un resumen de la estructura:

layers - |-circuit_panel (on top) |-grid_panel (at bottom) 

Quiero que el grid_panel permanezca estático, es decir, que no se vuelva a pintar (excepto el inicial) ya que no cambia.

El problema es que cada vez que llamo a circuit_panel.repaint (), grid_panel se vuelve a pintar también. Esto definitivamente no es eficiente.

Creo que esto se debe al ansioso comportamiento de pintura de JLayeredPane. ¿Hay alguna manera de desactivar esta característica en JLayeredPane?

En caso de que esté interesado en ver el efecto anterior, he escrito un pequeño progtwig de demostración:

 public class Test2 extends JFrame { public Test2() { JLayeredPane layers = new JLayeredPane(); layers.setPreferredSize(new Dimension(600, 400)); MyPanel1 myPanel1 = new MyPanel1(); MyPanel2 myPanel2 = new MyPanel2(); myPanel1.setSize(600, 400); myPanel2.setSize(600, 400); myPanel1.setOpaque(false); myPanel2.setOpaque(false); myPanel2.addMouseListener(new MyMouseListener(myPanel2)); layers.add(myPanel1, new Integer(100)); // At bottom layers.add(myPanel2, new Integer(101)); // On top this.getContentPane().add(layers, BorderLayout.CENTER); this.setSize(600, 400); } class MyPanel1 extends JPanel { Color getRandomColor() { int r = (int) (256 * Math.random()); int g = (int) (256 * Math.random()); int b = (int) (256 * Math.random()); return new Color(r, g, b); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setColor(getRandomColor()); g2d.fillRoundRect(30, 30, 60, 60, 5, 5); } } class MyPanel2 extends JPanel { Color getRandomColor() { int r = (int) (256 * Math.random()); int g = (int) (256 * Math.random()); int b = (int) (256 * Math.random()); return new Color(r, g, b); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setColor(getRandomColor()); g2d.fillRoundRect(45, 45, 75, 75, 5, 5); } } class MyMouseListener extends MouseAdapter { JPanel panel; MyMouseListener(JPanel panel) { this.panel = panel; } @Override public void mouseClicked(MouseEvent e) { panel.repaint(); } } /** * @param args */ public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { (new Test2()).setVisible(true); } }); } } 

Como descubriste, una BufferedImage es una forma efectiva de almacenar en caché contenido complejo para una representación eficiente; CellTest es un ejemplo. Un procesador de peso mosca, que se muestra aquí , es otro enfoque. Finalmente, he vuelto a factorizar su ejemplo instructivo de una manera que puede facilitar la experimentación.

Demostración de capa

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Random; import javax.swing.JFrame; import javax.swing.JLayeredPane; import javax.swing.JPanel; import javax.swing.SwingUtilities; /** @see https://stackoverflow.com/q/9625495/230513 */ public class LayerDemo extends JFrame { private static final Dimension d = new Dimension(320, 240); public LayerDemo() { JLayeredPane layers = new JLayeredPane(); layers.setPreferredSize(d); layers.add(new LayerPanel(1 * d.height / 8), 100); layers.add(new LayerPanel(2 * d.height / 8), 101); layers.add(new LayerPanel(3 * d.height / 8), 102); this.add(layers, BorderLayout.CENTER); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.pack(); this.setLocationByPlatform(true); } private static class LayerPanel extends JPanel { private static final Random r = new Random(); private int n; private Color color = new Color(r.nextInt()); public LayerPanel(int n) { this.n = n; this.setOpaque(false); this.setBounds(n, n, d.width / 2, d.height / 2); this.addMouseListener(new MouseHandler(this)); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setColor(color); g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 16, 16); g2d.setColor(Color.black); g2d.drawString(String.valueOf(n), 5, getHeight() - 5); } private void update() { color = new Color(r.nextInt()); repaint(); } } private static class MouseHandler extends MouseAdapter { LayerPanel panel; MouseHandler(LayerPanel panel) { this.panel = panel; } @Override public void mouseClicked(MouseEvent e) { panel.update(); } } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { (new LayerDemo()).setVisible(true); } }); } }