Concept: invisible buttons with circular and polygonal dispatch areas
First, you'll want a class defining an invisible button, extending javax.swing.AbstractButton so that it's still a fully functional button that you can add listeners to.
public abstract class InvisibleButton extends AbstractButton {
    public abstract boolean contains(Point point);
    @Override
    public boolean isVisible() {
        return false;
    }
}
Then, of course, you'll want implementations of that class. Here's two examples: one using a polygon for complex shapes, one using a circle.
public class PolygonalButton extends InvisibleButton {
    private Polygon area = null;
    public PolygonalButton(Polygon area) {
        this.area = area;
    }
    @Override
    public boolean contains(Point point) {
        return area.contains(point);
    }
}
public class CircularButton extends InvisibleButton {
    private int x;
    private int y;
    private double radius;
    public CircularButton(int x, int y, double radius) {
        this.x = x;
        this.y = y;
        this.radius = radius;
    }
    @Override
    public boolean contains(Point point) {
        double dx = x - point.x;
        double dy = y - point.y;
        return Math.sqrt(dx * dx + dy * dy) <= radius;
    }
}
Finally, you'll need to implement a container that handles all of these buttons, but you should use a panel instead of a frame.  Rather than hook each individual listener, you can simply override the frame's event processors and pass them to the necessary buttons.
public class InvisibleButtonImagePanel extends JPanel {
    private BufferedImage image = null;
    private List<InvisibleButton> buttons = new ArrayList<>();
    public InvisibleButtonImagePanel(BufferedImage image) {
        this.image = image;
    }
    public void add(InvisibleButton button) {
        buttons.add(button);
    }
    public void remove(InvisibleButton button) {
        buttons.remove(button);
    }
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(image.getWidth(), image.getHeight());
    }
    @Override
    public void processKeyEvent(KeyEvent event) {
        for (InvisibleButton button : buttons) {
            if (button.isFocusOwner()) {
                button.dispatchEvent(event);
            }
        }
        super.processKeyEvent(event);
    }
    @Override
    public void processMouseEvent(MouseEvent event) {
        for (InvisibleButton button : buttons) {
            if (button.contains(event.getPoint())) {
                button.dispatchEvent(event);
            }
        }
        super.processMouseEvent(event);
    }
    @Override
    protected void paintComponent(Graphics g) {
        g.drawImage(image, 0, 0, null);
        super.paintComponent(g);
    }
}
You'll probably want to rename the panel to something less bulky, and maybe implement your own advanced image code, but that's the basic idea behind it.