概要

マウスカーソルに反応するコンポーネントの領域をJLabelに設定した画像アイコンの不透明領域に合わせて変更します。

サンプルコード

BufferedImage image = ImageIO.read(getClass().getResource("duke.gif"));
JLabel label = new JLabel(new ImageIcon(image)) {
  @Override public boolean contains(int x, int y) {
    return super.contains(x, y) && ((image.getRGB(x, y) >> 24) & 0xFF) > 0;
  }
};
View in GitHub: Java, Kotlin

解説

  • JLabel#contains(int, int)メソッドをオーバーライドして与えられた座標にある画像の色成分が透明の場合はfalseを返すよう設定
  • 画像の透明部分はJLabelに含まれないことになりJLabelに設定したMouseListenerなどに反応しない
  • 非矩形画像の不透明部分だけが以下のようなMouseListenerでドラッグ可能になる
class ComponentMoveHandler extends MouseAdapter {
  private final Point startPt = new Point();

  @Override public void mousePressed(MouseEvent e) {
    startPt.setLocation(e.getPoint());
  }

  @Override public void mouseDragged(MouseEvent e) {
    Component c = e.getComponent();
    c.setLocation(c.getX() - startPt.x + e.getX(),
                  c.getY() - startPt.y + e.getY());
  }
}

参考リンク

コメント