Swing/ZoomingAndPanning のバックアップ(No.11)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/ZoomingAndPanning へ行く。
- 1 (2014-04-21 (月) 00:28:49)
- 2 (2014-04-21 (月) 14:42:00)
- 3 (2014-04-23 (水) 17:23:05)
- 4 (2014-08-29 (金) 00:30:12)
- 5 (2014-11-25 (火) 03:03:31)
- 6 (2015-11-25 (水) 21:21:19)
- 7 (2016-01-27 (水) 15:22:41)
- 8 (2017-06-27 (火) 13:56:33)
- 9 (2018-06-07 (木) 18:15:10)
- 10 (2020-06-02 (火) 19:04:26)
- 11 (2021-11-19 (金) 00:41:10)
- 12 (2022-08-05 (金) 16:00:52)
- 13 (2022-12-31 (土) 20:52:14)
- category: swing folder: ZoomingAndPanning title: JPanelに表示した画像のズームとスクロール tags: [AffineTransform, Graphics, JPanel, MouseListener, MouseMotionListener, MouseWheelListener] author: aterai pubdate: 2014-04-21T00:28:49+09:00 description: JPanelに表示した画像にAffineTransformによる変換を適用して、マウスを使った拡大・縮小・移動を実行します。 image:
概要
JPanel
に表示した画像にAffineTransform
による変換を適用して、マウスを使った拡大・縮小・移動を実行します。How to implement Zoom & Pan in Java using Graphics2Dに投稿されているコードを参考・引用しています。
Screenshot
Advertisement
サンプルコード
class ZoomAndPanHandler extends MouseAdapter {
private static final double ZOOM_MULTIPLICATION_FACTOR = 1.2;
private static final int MIN_ZOOM = -10;
private static final int MAX_ZOOM = 10;
private static final int EXTENT = 1;
private final BoundedRangeModel zoomRange = new DefaultBoundedRangeModel(
0, EXTENT, MIN_ZOOM, MAX_ZOOM + EXTENT);
private final AffineTransform coordAndZoomTransform = new AffineTransform();
private final Point dragStartPoint = new Point();
@Override public void mousePressed(MouseEvent e) {
dragStartPoint.setLocation(e.getPoint());
}
@Override public void mouseDragged(MouseEvent e) {
Point dragEndPoint = e.getPoint();
Point dragStart = transformPoint(dragStartPoint);
Point dragEnd = transformPoint(dragEndPoint);
coordAndZoomTransform.translate(dragEnd.x - dragStart.x, dragEnd.y - dragStart.y);
dragStartPoint.setLocation(dragEndPoint);
e.getComponent().repaint();
}
@Override public void mouseWheelMoved(MouseWheelEvent e) {
int dir = e.getWheelRotation();
int z = zoomRange.getValue();
zoomRange.setValue(z + EXTENT * (dir > 0 ? -1 : 1));
if (z == zoomRange.getValue()) {
return;
}
Component c = e.getComponent();
Rectangle r = c.getBounds();
// Point p = e.getPoint();
Point p = new Point(r.x + r.width / 2, r.y + r.height / 2);
Point p1 = transformPoint(p);
double scale = dir > 0 ? 1 / ZOOM_MULTIPLICATION_FACTOR
: ZOOM_MULTIPLICATION_FACTOR;
coordAndZoomTransform.scale(scale, scale);
Point p2 = transformPoint(p);
coordAndZoomTransform.translate(p2.getX() - p1.getX(), p2.getY() - p1.getY());
c.repaint();
}
// https://community.oracle.com/thread/1263955
// How to implement Zoom & Pan in Java using Graphics2D
private Point transformPoint(Point p1) {
Point p2 = new Point();
try {
AffineTransform inverse = coordAndZoomTransform.createInverse();
inverse.transform(p1, p2);
} catch (NoninvertibleTransformException ex) {
ex.printStackTrace();
}
return p2;
}
public AffineTransform getCoordAndZoomTransform() {
return coordAndZoomTransform;
}
}
View in GitHub: Java, Kotlin解説
AffineTransform#createInverse()
で取得したAffineTransform
オブジェクトでマウス位置の逆変換を行い、現在表示されている倍率でのズームの中心や移動距離などを計算しています。
- ズーム
- ホイール上回転で拡大
- ホイール下回転で縮小
- スクロール
- マウスドラッグで移動
参考リンク
- How to implement Zoom & Pan in Java using Graphics2D
- ズームとパンの機能を備えたドローソフトを作成する:CodeZine
- 2000ピクセル以上のフリー写真素材集
- タッチ操作に対応した画像ビューワーをJavaScriptで作るならD3.jsが便利 - てっく煮ブログ
- CanvasでAffine変換で大いにはまる(数学的センスが足りなかった・・・) - torutkの日記
- JScrollPane内に配置したJPanelをマウスで拡大、縮小、移動する