Swing/MouseDrivenImageRotation のバックアップの現在との差分(No.6)
- category: swing folder: MouseDrivenImageRotation title: Mouseで画像を移動、回転 tags: [ImageIcon, MouseListener, MouseMotionListener, AffineTransform] tags: [ImageIcon, MouseListener, MouseMotionListener, AffineTransform, Area] author: aterai pubdate: 2009-05-25T13:21:41+09:00 description: 画像をマウスのドラッグで任意の位置に移動、回転します。 image:
概要
画像をマウスのドラッグで任意の位置に移動、回転します。Life is beautiful: 習作UI:初めてのFlash その2、その3からの移植になります。概要
画像をマウスのドラッグで任意の位置に移動、回転します。Screenshot
Advertisement
サンプルコード
サンプルコード
#spandel
class DraggableImageMouseListener extends MouseAdapter{
#spanend
private static final Color color = new Color(100,255,200,100);
private static final int ir = 40, or = ir*3;
public final Ellipse2D.Double inner = new Ellipse2D.Double(0,0,ir,ir);
public final Ellipse2D.Double outer = new Ellipse2D.Double(0,0,or,or);
public final Image image;
public final int width;
public final int height;
public final double centerX, centerY;
public double x = 10.0, y = 50.0, rotate = 45.0 * (Math.PI / 180.0);
public double startX, startY, startA;
private boolean moverHover, rotatorHover;
#spanadd
class DraggableImageMouseListener extends MouseAdapter {
#spanend
private static final BasicStroke BORDER_STROKE = new BasicStroke(4f);
private static final Color BORDER_COLOR = Color.WHITE;
private static final Color HOVER_COLOR = new Color(100, 255, 200, 100);
private static final int IR = 40;
private static final int OR = IR * 3;
private final Shape border;
private final Shape polaroid;
private final RectangularShape inner = new Ellipse2D.Double(0, 0, IR, IR);
private final RectangularShape outer = new Ellipse2D.Double(0, 0, OR, OR);
private final Point2D startPt = new Point2D.Double();
private final Point2D centerPt = new Point2D.Double(100d, 100d);
private final Dimension imageSz;
private final Image image;
private double radian = Math.toRadians(45d); // 45d / 180d * Math.PI;
private double startRadian; // drag start radian
private boolean moverHover;
private boolean rotatorHover;
public DraggableImageMouseListener(ImageIcon ii) {
image = ii.getImage();
width = ii.getIconWidth();
height = ii.getIconHeight();
centerX = width/2.0;
centerY = height/2.0;
inner.x = (x+centerX-ir/2);
inner.y = (y+centerY-ir/2);
outer.x = (x+centerX-or/2);
outer.y = (y+centerY-or/2);
protected DraggableImageMouseListener(ImageIcon ii) {
super();
image = ii.getImage();
int width = ii.getIconWidth();
int height = ii.getIconHeight();
imageSz = new Dimension(width, height);
border = new RoundRectangle2D.Double(0, 0, width, height, 10, 10);
polaroid = new Rectangle2D.Double(-2, -2, width + 4, height + 20);
setCirclesLocation(centerPt);
}
public void paint(Graphics g, ImageObserver ior) {
Graphics2D g2d = (Graphics2D)g;
AffineTransform at = AffineTransform.getTranslateInstance(x, y);
at.rotate(rotate, centerX, centerY);
g2d.drawImage(image, at, ior);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if(rotatorHover) {
#spanadd
#spanend
private void setCirclesLocation(Point2D center) {
double cx = center.getX();
double cy = center.getY();
inner.setFrameFromCenter(cx, cy, cx + IR / 2d, cy - IR / 2d);
outer.setFrameFromCenter(cx, cy, cx + OR / 2d, cy - OR / 2d);
}
#spanadd
#spanend
public void paint(Graphics g, ImageObserver observer) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
#spanadd
#spanend
double w2 = imageSz.width / 2d;
double h2 = imageSz.height / 2d;
AffineTransform at = AffineTransform.getTranslateInstance(
centerPt.getX() - w2, centerPt.getY() - h2);
at.rotate(radian, w2, h2);
#spanadd
#spanend
g2.setPaint(BORDER_COLOR);
g2.setStroke(BORDER_STROKE);
Shape s = at.createTransformedShape(polaroid);
g2.fill(s);
g2.draw(s);
#spanadd
#spanend
g2.drawImage(image, at, observer);
#spanadd
#spanend
if (rotatorHover) {
Area donut = new Area(outer);
donut.subtract(new Area(inner));
g2d.setPaint(color);
g2d.fill(donut);
}else if(moverHover) {
g2d.setPaint(color);
g2d.fill(inner);
g2.setPaint(HOVER_COLOR);
g2.fill(donut);
} else if (moverHover) {
g2.setPaint(HOVER_COLOR);
g2.fill(inner);
}
#spanadd
#spanend
g2.setPaint(BORDER_COLOR);
g2.setStroke(BORDER_STROKE);
g2.draw(at.createTransformedShape(border));
g2.dispose();
}
#spanadd
#spanend
@Override public void mouseMoved(MouseEvent e) {
if(outer.contains(e.getX(), e.getY()) && !inner.contains(e.getX(), e.getY())) {
moverHover = false; rotatorHover = true;
}else if(inner.contains(e.getX(), e.getY())) {
moverHover = true; rotatorHover = false;
}else{
moverHover = rotatorHover =false;
if (outer.contains(e.getX(), e.getY())
&& !inner.contains(e.getX(), e.getY())) {
moverHover = false;
rotatorHover = true;
} else if (inner.contains(e.getX(), e.getY())) {
moverHover = true;
rotatorHover = false;
} else {
moverHover = false;
rotatorHover = false;
}
((JComponent)e.getSource()).repaint();
e.getComponent().repaint();
}
#spanadd
#spanend
@Override public void mouseReleased(MouseEvent e) {
rotatorHover = moverHover = false;
((JComponent)e.getSource()).repaint();
rotatorHover = false;
moverHover = false;
e.getComponent().repaint();
}
#spanadd
#spanend
@Override public void mousePressed(MouseEvent e) {
if(outer.contains(e.getX(), e.getY()) && !inner.contains(e.getX(), e.getY())) {
if (outer.contains(e.getX(), e.getY())
&& !inner.contains(e.getX(), e.getY())) {
rotatorHover = true;
startA = rotate - Math.atan2(e.getY()-y-centerY, e.getX()-x-centerX);
((JComponent)e.getSource()).repaint();
}else if(inner.contains(e.getX(), e.getY())) {
startRadian = radian - Math.atan2(
e.getY() - centerPt.getY(), e.getX() - centerPt.getX());
e.getComponent().repaint();
} else if (inner.contains(e.getX(), e.getY())) {
moverHover = true;
startX = e.getX();
startY = e.getY();
((JComponent)e.getSource()).repaint();
startPt.setLocation(e.getPoint());
e.getComponent().repaint();
}
}
#spanadd
#spanend
@Override public void mouseDragged(MouseEvent e) {
if(rotatorHover) {
rotate = startA + Math.atan2(e.getY()-y-centerY, e.getX()-x-centerX);
((JComponent)e.getSource()).repaint();
}else if(moverHover) {
x += e.getX() - startX;
y += e.getY() - startY;
inner.x = (x+centerX-ir/2);
inner.y = (y+centerY-ir/2);
outer.x = (x+centerX-or/2);
outer.y = (y+centerY-or/2);
startX = e.getX();
startY = e.getY();
((JComponent)e.getSource()).repaint();
if (rotatorHover) {
radian = startRadian + Math.atan2(
e.getY() - centerPt.getY(), e.getX() - centerPt.getX());
e.getComponent().repaint();
} else if (moverHover) {
centerPt.setLocation(
centerPt.getX() + e.getX() - startPt.getX(),
centerPt.getY() + e.getY() - startPt.getY());
setCirclesLocation(centerPt);
startPt.setLocation(e.getPoint());
e.getComponent().repaint();
}
}
}
View in GitHub: Java, Kotlin解説
画像の中心をドラッグすると移動、すこし外側をドラッグすると画像を回転することができます。解説
- 画像の移動: 画像の中心にマウスが近づくと表示される円図形をドラッグ
- 画像の回転: 上記の円図形の外側に表示されるドーナツ型図形をドラッグ
- ドーナツ型図形は
Area#subtract(Area)
メソッドを使用して作成可能
- ドーナツ型図形は
- -
回転のためのドーナツ状の図形は、
Area#subtract
メソッドを使用して作成しています。