Não é possível pintar um componente personalizado no Swing corretamente

Conheço Swing muito mal, desculpe-me por perguntas estúpidas. O que preciso fazer é criar meus componentes personalizados (eles são ancestrais deJPanel) com a pintura realizada a partir do buffer (BufferedImage instância). É um requisito, porque o procedimento de pintura pode ser muito pesado, portanto o método paintComponent é substituído para extrair desse buffer e retornar imediatamente (mas se você souber maneiras melhores de dizer ao Java para não repintar o objeto entre 200 e 300 vezes por segundo) toda a CPU - eu apreciaria, talvez haja alguns métodos públicos para marcar regiões do contexto gráfico como "não alteradas", para que o Swing não tente repintá-las).

O que há de errado com meu código que ele simplesmente não extrai dados sobre JPanels sobrepostos. Fiz um exemplo reproduzível do núcleo do problema. Veja o código abaixo:

public class Dr extends JPanel {

    public Dr(int x, int y, int w, int h, int fw, int fh) {
        left = x;
        top = y;
        width = w;
        height = h;
        full_width = fw;
        full_height = fh;
        setOpaque(true);
    }

    public void draw() {
        if (buffer == null && width > 0 && height > 0) {
            buffer = new BufferedImage(width, height, java.awt.image.BufferedImage.TYPE_INT_ARGB);
        }
        if (buffer == null) return;
        Graphics g = buffer.getGraphics();
        setBounds(0, 0, full_width, full_height);
        Graphics2D g2d = (Graphics2D)g;
        g2d.setBackground(Color.WHITE);
        g2d.clearRect(0, 0, full_width, full_height);

        g2d.setColor(new Color(255, 0, 80, 128));

        g2d.fillRect(left, top, width, height);
        System.out.println(left + ", " +  top);
    }

    @Override
    public void repaint() {
        draw();
    }

    @Override
    public void paintComponent(Graphics g) {
        g.drawImage(buffer, 0, 0, null);
    }

    private BufferedImage buffer;

    private int left;
    private int top;
    private int width;
    private int height;
    private int full_width;
    private int full_height;
}

Esta é uma classe de amostra que não faz nada além de salvar suas coordenadas para desenhar em e dimensões completas (que eu quero que sejam iguais às dimensões pai, isso é um requisito novamente porque eu preciso dar suporte ao conteúdo transbordante visível para poder ser exibido) e desenhando um retângulo vermelho com metade da opacidade de 100%.

Aqui está o código externo que o usa:

    Dr dr1 = new Dr(4, 4, width-10, 80, width-2, height-2);
    Dr dr2 = new Dr(4, 88, width-10, 80, width-2, height-2);
    root.add(dr1);
    root.add(dr2);
    dr1.setBounds(0, 0, width-2, height-2);
    dr2.setBounds(0, 0, width-2, height-2);
    dr1.draw();
    dr2.draw();

O que se espera ser:

O que é exibido quando eu removo meu buffer e puxopaintComponent método diretamente:

O que é exibido quando não preencho o plano de fundo (aqui o plano de fundo tem a cor L&F do sistema, mas preciso da cor do pai do elemento (no meu exemplo, é branco)

O que é exibido quando eu drraw do meu buffer

O último é completamente divertido. O retângulo vermelho é parcialmente cortado da direita e da parte inferior, e a imagem completa (incluindo o fundo branco) é cortada da coordenada (0, 0) do painel pai. O segundo objeto não é exibido. As coordenadas no console estão absolutamente OK.

Sinto que há algo que tenho a ver com o Swing para dizer a ele para não executar sua "mágica" ao adivinhar o que pintar e o que não pintar. Mas como posso fazer isso?

ATUALIZAR:

Eu descobri que mesmo se eu não ligardraw() método dos componentes filhos depois que os adicionei, eles ainda ocultam os antecedentes de seus pais (o que não deve acontecer, os JPase de bacase devem ser opacos). Portanto, o principal problema é que não posso fazer minhaDr os objetos têm um fundo opaco (por exemplo, sem fundo), onde nada é pintado neles (também explica por que vejo apenas o primeiro retângulo - a ordem z no Swing parece estar invertida, por exemplo, o último componente adicionado é pintado na parte inferior, como foi o mais distante de nós).

questionAnswers(2)

yourAnswerToTheQuestion