Swing/PaintPanel のバックアップの現在との差分(No.10)
TITLE:JPanelにマウスで自由曲線を描画
Posted by terai at 2005-12-19
JPanelにマウスで自由曲線を描画
- category: swing folder: PaintPanel title: JPanelにマウスで自由曲線を描画 tags: [JPanel, MouseListener, MouseMotionListener] author: aterai pubdate: 2005-12-19T14:19:26+09:00 description: マウスをドラッグしてパネル上に自由曲線を描画します。 image:
概要
マウスをドラッグしてパネル上に自由曲線を描画します。- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
#screenshot
サンプルコード
#spanend
#spanadd
class PaintPanel extends JPanel {
#spanend
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;
#spandel
**サンプルコード [#jb2b9b9e]
#spanend
#spandel
#code{{
#spanend
#spandel
class PaintPanel extends JPanel implements MouseMotionListener, MouseListener {
#spanend
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) {}
#spandel
}
#spanend
#spandel
View in GitHub: Java, Kotlin解説
上記のサンプルでは、パネル上でマウスがドラッグされている場合、その軌跡を短い直線でつなぎ合わせて描画することで、お絵かきしています。- マウスがクリックされた場所を始点にする
- ドラッグされた時の位置を終点にしてパネルをrepaint
- paintComponentをオーバーライドして、上記の始点、終点で直線を描画
- 次の直線のための始点を現在の終点に変更
コメント
- マウス右ボタンをドラッグで消しゴム…のテスト -- terai
#spanend #spandel import java.awt.*; #spanend #spandel import java.awt.event.*; #spanend #spandel import java.awt.geom.*; #spanend #spandel import java.awt.image.*; #spanend #spandel import javax.swing.*; #spanend #spandel #spanend #spandel class PaintPanel2 extends JPanel implements MouseMotionListener, MouseListener { #spanend public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { createAndShowGUI(); @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(); } }); } public static void createAndShowGUI() { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.getContentPane().add(new PaintPanel2()); frame.setSize(320, 240); frame.setLocationRelativeTo(null); frame.setVisible(true); } private final Polygon polygon = new Polygon(); private Point startPoint = new Point(-1,-1); private BufferedImage offImage = null; private BufferedImage backImage = null; private TexturePaint texture = makeTexturePaint(); private int[] pix = new int[320 * 240]; public PaintPanel2() { super(); addMouseMotionListener(this); addMouseListener(this); offImage = new BufferedImage(320, 240, BufferedImage.TYPE_4BYTE_ABGR); PixelGrabber pg = new PixelGrabber(offImage, 0, 0, 320, 240, pix, 0, 320); try { pg.grabPixels(); } catch (Exception e) { e.printStackTrace(); } backImage = new BufferedImage(320, 240, BufferedImage.TYPE_4BYTE_ABGR); Graphics2D g2 = backImage.createGraphics(); g2.setPaint(texture); g2.fillRect(0,0,320,240); g2.dispose(); } #spandel #spanend private static BufferedImage makeBGImage() { Color color = new Color(200,150,100,50); int cs = 6, sz = cs*cs; BufferedImage img = new BufferedImage(sz,sz,BufferedImage.TYPE_4BYTE_ABGR); Graphics2D g2 = img.createGraphics(); g2.setPaint(color); g2.fillRect(0,0,sz,sz); for (int i=0; i*cs<sz; i++) { for (int j=0; j*cs<sz; j++) { if ((i+j)%2==0) g2.fillRect(i*cs, j*cs, cs, cs); @Override public void mouseDragged(MouseEvent e) { Point p = e.getPoint(); path.lineTo(p.x, p.y); repaint(); } } g2.dispose(); return img; }; addMouseMotionListener(handler); addMouseListener(handler); list = new ArrayList<Shape>(); } private static TexturePaint makeTexturePaint() { BufferedImage img = makeBGImage(); int w = img.getWidth(), h = img.getHeight(); Rectangle2D r2d = new Rectangle2D.Float(0,0,w,h); return new TexturePaint(img, r2d); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); if (backImage!=null) { ((Graphics2D)g).drawImage(backImage, 0, 0, this); } if (offImage!=null) { MemoryImageSource producer = new MemoryImageSource(320, 240, pix, 0, 320); g.drawImage(createImage(producer), 0, 0, null); g.dispose(); } } int penc = 0x0; public void mouseDragged(MouseEvent e) { Point pt = e.getPoint(); double xDelta = e.getX() - startPoint.getX(); double yDelta = e.getY() - startPoint.getY(); double delta = Math.max(Math.abs(xDelta), Math.abs(yDelta)); double xIncrement = xDelta / delta; double yIncrement = yDelta / delta; double xStart = startPoint.x; double yStart = startPoint.y; for (int i=0; i<delta; i++) { Point p = new Point((int)xStart, (int)yStart); if (p.x<0 || p.y<0 || p.x>=320 || p.y>=240) break; pix[p.x + p.y * 320] = penc; for(int n=-1;n<=1;n++) { for(int m=-1;m<=1;m++) { int t = (p.x+n) + (p.y+m) * 320; if(t>=0 && t<320*240) { pix[t] = penc; } } @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); } repaint(p.x-2, p.y-2, 4, 4); xStart += xIncrement; yStart += yIncrement; g2.dispose(); } startPoint = pt; } private Rectangle getRepaintRectangle(Point srcPoint, Point destPoint) { polygon.reset(); polygon.addPoint(srcPoint.x, srcPoint.y); polygon.addPoint(destPoint.x, srcPoint.y); polygon.addPoint(destPoint.x, destPoint.y); polygon.addPoint(srcPoint.x, destPoint.y); return polygon.getBounds(); } public void mousePressed(MouseEvent e) { startPoint = e.getPoint(); penc = (e.getButton()==MouseEvent.BUTTON1)?0xff000000:0x0; } 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) {} }
解説
上記のサンプルでは、パネル上でマウスがドラッグされた場合その軌跡を短い直線でつなぎ合わせることで曲線を描画しています。- 新規
Path2D
を生成してマウスがクリックされた場所をPath2D.moveTo(...)
で始点に設定 - ドラッグされた時の位置を
Path2D.lineTo(...)
で終点にしてパネルをrepaint()
-
paintComponent(...)
をオーバーライドして、上記の直線のリスト(Path2D
のリスト)を描画 - 次の直線のための始点を現在の終点に変更
参考リンク
コメント
- マウス右ボタンをドラッグで消しゴム…のテスト -- aterai
- 追記:不要なコードを削除。 -- aterai
- MemoryImageSourceで配列から画像を生成に移動。 -- aterai
- わからん!! --
- 直線を
Path2D
で保存する方法に変更。 -- aterai