Não, o problema é mais embaixo. Está relacionado a forma que os componentes trabalham.
A AWT tenta fazer janelas usando recursos do SO. Quando você desenha um botão, a AWT usa a API do Windows para desenhar um botão. O mesmo vale para qualquer outro componente. Isso é chamado de componente “heavy weight” (pesado).
O Swing não trabalha assim. Ele cria um único canvas, acelerado por hardware, e após isso, faz ele mesmo o desenho usando java 2D. Esse desenho é feito usando alguma biblioteca de pintura acelerada, como OpenGL ou, no caso do Windows, DirectX. No Swing, quando um botão é desenhado, ele é efetivamente pintado sobre o painel, não há a criação de componentes do Windows adicionais. Por isso, ele também consome menos recursos do SO, e é chamado de “light weight” (leve).
Quando vc mistura as duas coisas ocorrem alguns efeitos indesejados:
- Todos os componentes da AWT ficam SOBRE os componentes do Swing. Isso pq o botão é um componente da GDI, que está sobre o canvas, e os componentes do Swing são a “pintura” desse mesmo canvas;
- Eventos podem se perder. A captura dos eventos dos componentes da AWT não é propagada para os componentes Swing;
- Não é possível usar componentes como o JScrollPane sobre componentes da AWT.
- Layout managers também não funcionam como deveriam.
Esse artigo explica em detalhes essas situações: http://java.sun.com/j2se/1.3/docs/guide/awt/designspec/lightweights.html
Para pintar no Swing, substitua a classe Canvas pela classe JComponent. Se precisar de um componente que suporte outros em cima dele, faça um filho de JPanel. E lembre-se que no caso do Swing o método que deve ser sobrescrito para pintura é o paintComponent, não o método paint.