Swing/ZoomingAndPanning のバックアップ(No.13)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - 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_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 coordAndZoomAtf = new AffineTransform();
private final Point2D dragStartPoint = new Point();
@Override public void mousePressed(MouseEvent e) {
dragStartPoint.setLocation(e.getPoint());
}
@Override public void mouseDragged(MouseEvent e) {
Point2D dragEndPoint = e.getPoint();
Point2D dragStart = transformPoint(dragStartPoint);
Point2D dragEnd = transformPoint(dragEndPoint);
coordAndZoomAtf.translate(
dragEnd.getX() - dragStart.getX(), dragEnd.getY() - dragStart.getY());
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();
Point2D p = new Point2D.Double(r.getCenterX(), r.getCenterY());
Point2D p1 = transformPoint(p);
double scale = dir > 0 ? 1 / ZOOM_FACTOR : ZOOM_FACTOR;
coordAndZoomAtf.scale(scale, scale);
Point2D p2 = transformPoint(p);
coordAndZoomAtf.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 Point2D transformPoint(Point2D p1) {
AffineTransform inverse = coordAndZoomAtf;
boolean hasInverse = coordAndZoomAtf.getDeterminant() != 0d;
if (hasInverse) {
try {
inverse = coordAndZoomAtf.createInverse();
} catch (NoninvertibleTransformException ex) {
// should never happen
assert false;
}
}
Point2D p2 = new Point();
inverse.transform(p1, p2);
return p2;
}
public AffineTransform getCoordAndZoomTransform() {
return coordAndZoomAtf;
}
}
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をマウスで拡大、縮小、移動する