マウスイベントを親コントロールに透過させる

SwingコンポーネントはsetOpaque(false)で背景を透明にできますが、その場合でもマウスイベントはコントロール領域内で捕捉されます。

マウスイベントも透過させたい場合は、以下のようにすれば良いようです。これを応用すれば、不定形のコントロールを作ってオーバーレイさせたりできます。

public class MouseEventManipulator {
    public void delegateMouseEventsToParent(Component c) {
        c.addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent e) {
                passToParent(e);
            }

            public void mouseEntered(MouseEvent e) {
                passToParent(e);
            }

            public void mouseExited(MouseEvent e) {
                passToParent(e);
            }

            public void mousePressed(MouseEvent e) {
                passToParent(e);
            }

            public void mouseReleased(MouseEvent e) {
                passToParent(e);
            }
        });
        c.addMouseMotionListener(new MouseMotionListener() {
            public void mouseDragged(MouseEvent e) {
                passToParent(e);
            }

            public void mouseMoved(MouseEvent e) {
                passToParent(e);
            }
        });
    }

    private void passToParent(MouseEvent e) {
        Component c = (Component) e.getSource();
        Component parent = c.getParent();
        Point p = SwingUtilities.convertPoint(c, e.getPoint(), parent);
        MouseEvent newEvent = new MouseEvent(parent, e.getID(), e.getWhen(),
                e.getModifiers(), p.x, p.y, e.getClickCount(),
                e.isPopupTrigger());
        parent.dispatchEvent(newEvent);
    }
}