TITLE:JComponentの形状を変更する
Posted by aterai at 2008-11-17

JComponentの形状定義を変更する

コンポーネントの形状を画像の不透明領域に合わせて変更します。
  • category: swing folder: MoveNonRectangularImage title: JComponentの形状を変更する tags: [JComponent, JLabel, BufferedImage, DragAndDrop] author: aterai pubdate: 2008-11-17T16:07:53+09:00 description: マウスカーソルに反応するコンポーネントの領域をJLabelに設定した画像アイコンの不透明領域に合わせて変更します。 image: https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTQKdiDk4I/AAAAAAAAAfI/tb322r8ngL0/s800/MoveNonRectangularImage.png

概要

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

サンプルコード

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

サンプルコード

解説

  • JLabel#contains(int, int)メソッドをオーバーライドして与えられた座標にある画像の色成分が透明の場合はfalseを返すよう設定
  • 画像の透明部分はJLabelに含まれないことになりJLabelに設定したMouseListenerなどに反応しない
  • 非矩形画像の不透明部分だけが以下のようなMouseListenerでドラッグ可能になる
#spandel
ImageIcon i = new ImageIcon(getClass().getResource("duke.gif"));
#spanend
#spandel
Dimension d = new Dimension(i.getIconWidth(), i.getIconHeight());
#spanend
#spandel
final BufferedImage image = new BufferedImage(d.width,d.height,BufferedImage.TYPE_INT_ARGB);
#spanend
#spandel
Graphics g = image.createGraphics();
#spanend
#spandel
i.paintIcon(null,g,0,0);
#spanend
#spandel
g.dispose();
#spanend
#spandel
final JLabel icon = new JLabel(i) {
#spanend
  public boolean contains(int x, int y) {
    return super.contains(x, y) && ((image.getRGB(x, y) >> 24) & 0xff) > 0;
#spanadd
class ComponentMoveHandler extends MouseAdapter {
#spanend
  private final Point startPt = new Point();
#spanadd

#spanend
  @Override public void mousePressed(MouseEvent e) {
    startPt.setLocation(e.getPoint());
  }
#spandel
};
#spanend
#spandel
icon.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
#spanend
#spandel
MouseAdapter l = new MouseAdapter() {
#spanend
  private Point start;
  private Point loc;
  public void mousePressed(MouseEvent me) {
    start = me.getPoint();
#spanadd

#spanend
  @Override public void mouseDragged(MouseEvent e) {
    Component c = e.getComponent();
    c.setLocation(c.getX() - startPt.x + e.getX(),
                  c.getY() - startPt.y + e.getY());
  }
  public void mouseDragged(MouseEvent me) {
    loc = icon.getLocation(loc);
    int x = loc.x - start.x + me.getX();
    int y = loc.y - start.y + me.getY();
    icon.setLocation(x, y);
  }
#spandel
};
#spanend
#spandel
icon.addMouseListener(l);
#spanend
#spandel
icon.addMouseMotionListener(l);
#spanend
#spanadd
}
#spanend

解説

上記のサンプルでは、非矩形画像の不透明部分だけマウスでドラッグできるように、マウス処理にUIが使用する contains メソッドをオーバーライドし、透明部分がJLabelの形状に含まれないようにしています。

参考リンク

参考リンク

コメント

コメント