• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JPanelにマウスで自由曲線を描画
*JPanelにマウスで自由曲線を描画 [#n9266a0a]
>編集者:[[Terai Atsuhiro>terai]]~
作成日:2005-12-19~
更新日:&lastmod;
---
category: swing
folder: PaintPanel
title: JPanelにマウスで自由曲線を描画
tags: [JPanel, MouseListener, MouseMotionListener]
author: aterai
pubdate: 2005-12-19T14:19:26+09:00
description: マウスをドラッグしてパネル上に自由曲線を描画します。
image: https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTQ0y2U6WI/AAAAAAAAAgM/AAHllQ3_VHw/s800/PaintPanel.png
---
* 概要 [#summary]
マウスをドラッグしてパネル上に自由曲線を描画します。

#contents
#download(https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTQ0y2U6WI/AAAAAAAAAgM/AAHllQ3_VHw/s800/PaintPanel.png)

**概要 [#hbac2d36]
マウスでパネルにお絵かきします。
* サンプルコード [#sourcecode]
#code(link){{
class PaintPanel extends JPanel {
  private static final Stroke STROKE = new BasicStroke(
      3f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
  private transient List<Shape> list;
  private transient Path2D path;
  private transient MouseAdapter handler;

#screenshot
  @Override public void updateUI() {
    removeMouseMotionListener(handler);
    removeMouseListener(handler);
    super.updateUI();
    handler = new MouseAdapter() {
      @Override public void mousePressed(MouseEvent e) {
        path = new Path2D.Double();
        list.add(path);
        Point p = e.getPoint();
        path.moveTo(p.x, p.y);
        repaint();
      }

**サンプルコード [#jb2b9b9e]
 class PaintPanel extends JPanel implements MouseMotionListener, MouseListener {
   private Point startPoint = new Point(-1,-1);
   private Point endPoint   = new Point(-1,-1);
   public PaintPanel() {
     super();
     addMouseMotionListener(this);
     addMouseListener(this);
   }
   public void paintComponent(Graphics g) {
     //super.paintComponent(g);
     Graphics2D g2d = (Graphics2D)g;
     g2d.setStroke(new BasicStroke(3.0F));
     g2d.setPaint(Color.black);
     g2d.drawLine(startPoint.x, startPoint.y,
                  endPoint.x,   endPoint.y);
     startPoint = endPoint;
   }
   public void mouseDragged(MouseEvent e) {
     endPoint = e.getPoint();
     repaint();
   }
   public void mousePressed(MouseEvent e) {
     startPoint = e.getPoint();
   }
   public void mouseMoved(MouseEvent e) {}
   public void mouseExited(MouseEvent e) {}
   public void mouseEntered(MouseEvent e) {}
   public void mouseReleased(MouseEvent e) {}
   public void mouseClicked(MouseEvent e) {}
 }
      @Override public void mouseDragged(MouseEvent e) {
        Point p = e.getPoint();
        path.lineTo(p.x, p.y);
        repaint();
      }
    };
    addMouseMotionListener(handler);
    addMouseListener(handler);
    list = new ArrayList<Shape>();
  }

-&jnlp;
-&jar;
-&zip;
  @Override protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (list != null) {
      Graphics2D g2 = (Graphics2D) g.create();
      g2.setPaint(Color.BLACK);
      g2.setStroke(STROKE);
      for (Shape s : list) {
        g2.draw(s);
      }
      g2.dispose();
    }
  }
}
}}

**解説 [#t35e18f2]
上記のサンプルでは、短い直線をパネル上に描画することで、お絵かきをしています。
* 解説 [#explanation]
上記のサンプルでは、パネル上でマウスがドラッグされた場合その軌跡を短い直線でつなぎ合わせることで曲線を描画しています。

- マウスがクリックされた場所を始点にする
- ドラッグされた時の位置を終点にしてパネルをrepaint
- paintComponentをオーバーライドして、上記の始点、終点で直線を描画
- 新規`Path2D`を生成してマウスがクリックされた場所を`Path2D.moveTo(...)`で始点に設定
- ドラッグされた時の位置を`Path2D.lineTo(...)`で終点にしてパネルを`repaint()`
- `paintComponent(...)`をオーバーライドして、上記の直線のリスト(`Path2D`のリスト)を描画
- 次の直線のための始点を現在の終点に変更

**参考リンク [#xd23e0cf]
-[[Painting in AWT and Swing>http://java.sun.com/products/jfc/tsc/articles/painting/#swing]]
* 参考リンク [#reference]
- [[MemoryImageSourceで配列から画像を生成>Swing/MemoryImageSource]]

**コメント [#j1077dd9]
* コメント [#comment]
#comment
- マウス右ボタンをドラッグで消しゴム…のテスト -- &user(aterai); &new{2010-01-12 (火) 16:16:59};
-- 追記:不要なコードを削除。 -- &user(aterai); &new{2010-04-30 (金) 19:26:37};
-- [[MemoryImageSourceで配列から画像を生成>Swing/MemoryImageSource]]に移動。 -- &user(aterai); &new{2010-06-07 (月) 15:21:37};
- わからん!! --  &new{2010-04-30 (金) 18:11:55};
- 直線を`Path2D`で保存する方法に変更。 -- &user(aterai); &new{2015-12-08 (火) 16:16:59};

#comment