title: Java painting mechanism on OverlayLayout
body: <p>Is there a way to create a layered system of components in Java so that at one moment only one layer will be updated (repainted)?</p>
  <p>The simplest example would be a large map, with thousands of shapes and labels that will be placed on a &quot;bottom&quot; layer. And on the &quot;top&quot; layer you have another small shape, a custom tooltip would be a good example for this scenario. Now, whenever the tooltip's position is getting updated (by mouse move), even if you specifically call repaint() on that component only, the whole frame is being updated (thus a repaint is called on each layer, making the whole system pretty slow and ineffective).</p>
  <p>I know you can achieve some optimization by caching contents as images and paint images instead of thousands of shapes, but, still, I'm interested in a &quot;simpler&quot; solution.</p>
  <p>Thank you.</p>
  <p>Sample code:</p>
  <p>Basically there is a main frame (m) which loads a container (mc) and this container has two &quot;layers&quot; (ml). Now, when I call repaint() just for the 2nd layer, it's easy to see all paintComponent() are called again (console text appears but also BOTH rectangles change color to a new random one). And that is what I need to prevent.</p>
  <p><strong>File: m.java</strong></p>
  <pre><code>import javax.swing.JFrame;
  import java.awt.EventQueue;
  import java.util.Timer;
  import java.util.TimerTask;
   
  public class m extends JFrame {
   
      public mc omc;
   
      public m() {
          initUI();
      }
   
      private void initUI() {
          this.pack();
          this.setSize(600, 680);
          this.setResizable(true);
          this.setLocationRelativeTo(null);
          this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          this.setVisible(true);
   
          this.omc = new mc();
          this.add(omc);
   
          m self = this;
          Timer oTimer = new Timer();
          oTimer.schedule(new TimerTask() {
              @Override
              public void run() {
                  self.omc.oml1.repaint();
              }
          }, 2000);
   
      }
   
      public static void main(String[] args) {
          EventQueue.invokeLater(new Runnable() {
              public void run() {
                  m ex = new m();
                  ex.setVisible(true);
              }
          });
      }
  }
  </code></pre>
  <p><strong>File: mc.java</strong></p>
  <pre><code>import javax.swing.JPanel;
  import javax.swing.OverlayLayout;
  import java.awt.Graphics;
   
  public class mc extends JPanel {
   
      public ml oml0;
      public ml oml1;
   
      public mc() {
          this.setLayout(new OverlayLayout(this));
          this.oml0 = new ml(0);
          this.oml1 = new ml(1);
   
          this.add(oml0);
          this.add(oml1);
      }
   
      public void paintComponent(Graphics g) {
          System.out.println(&quot;mc&quot;);
          super.paintComponent(g);
      }
   
  }
  </code></pre>
  <p><strong>File: ml.java</strong></p>
  <pre><code>import javax.swing.JPanel;
  import java.awt.Color;
  import java.awt.Graphics;
  import java.awt.Graphics2D;
   
  public class ml extends JPanel {
   
      private int l = 0;
   
      public ml(int ll) {
          this.l = ll;
          this.setOpaque(false);
      }
   
      public void paintComponent(Graphics g) {
          System.out.println(&quot;ml:&quot; + this.l);
          super.paintComponent(g);
   
          Graphics2D g2d = (Graphics2D)g;
   
          if (this.l == 0) {
              g2d.setPaint(new Color((int)Math.round(100 + 150 * Math.random()), (int)Math.round(100 + 150 * Math.random()), (int)Math.round(100 + 150 * Math.random())));
              g2d.fillRect(30, 30, 300, 100);
          }
          if (this.l == 1) {
              g2d.setPaint(new Color((int)Math.round(100 + 150 * Math.random()), (int)Math.round(100 + 150 * Math.random()), (int)Math.round(100 + 150 * Math.random())));
              g2d.fillRect(130, 80, 300, 100);
          }
      }
   
  }
  </code></pre>