问题描述
我想像这样简单地在 for 循环中旋转图像:
I am trying to simply rotate an image in a for loop like so:
class MyCanvas extends JComponent {
AffineTransform identity = new AffineTransform();
Image arrow;
Double angle = -180.0;
public void spin() {
angle += 10.0;
for(int i = 0; i < 10; i++) {
repaint();
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
arrow = Toolkit.getDefaultToolkit().getImage("red-arrow-right-th.png");
// Rotate + translate
AffineTransform trans = new AffineTransform();
trans.setTransform(identity);
trans.translate(getWidth()/2, getHeight()/2);
trans.rotate(Math.toRadians(angle));
System.out.println(trans);
g2.drawImage(arrow, trans, this);
g2.finalize();
}
}
然而,当我在 main 中运行 call spin()
时,它似乎只应用了一次旋转,同时仍然正确地打印出循环.我忽略了什么?
However when I run call spin()
in main, it appears to apply only a single rotation, whilst still printing out the loop correctly. What am I overlooking something?
推荐答案
我已经使用 MadProgrammer 的推荐转换了您的代码:
I've transformed your code using the recommendation of MadProgrammer:
- 不要覆盖
paint
,覆盖paintComponent
. - 在执行任何自定义绘画之前调用
super.paint
, - 永远不要对任何东西调用
finalize
,尤其不要对不是你自己创建的对象调用. - 使用摇摆计时器
- Don't override
paint
, overridepaintComponent
. - Call
super.paint
before performing any custom painting, - Never call
finalize
on anything and especially not on objects you didn't create yourself. - Use a Swing Timer
注意以下事项
A 限定此用于从 ActionListener 内部类访问 ImageRotationView 实例.
A qualified this is used to access the ImageRotationView instance from the ActionListener inner class.
AffineTransform.getRotateInstance
返回一个围绕锚点旋转坐标的变换.
AffineTransform.getRotateInstance
returns a transform that rotates coordinates around an anchor point.
.
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.Timer;
public class ImageRotationFrame {
public static void main(String[] args) {
new ImageRotationFrame();
}
public ImageRotationFrame() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Testing");
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new ImageRotationComponent());
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
private class ImageRotationComponent extends JComponent {
Image arrow;
double angle = 0.0;
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
angle += 0.4;
AffineTransform trans = AffineTransform.getRotateInstance(angle, getWidth() / 2, getHeight() / 2);
((Graphics2D) g).drawImage(arrow, trans, this);
}
public ImageRotationComponent() {
try {
arrow = ImageIO.read(new File("dice.png"));
} catch (IOException e) {
e.printStackTrace();
}
int delay = 500; //milliseconds
ActionListener taskPerformer = new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
ImageRotationComponent.this.repaint();
}
};
new Timer(delay, taskPerformer).start();
}
}
}
这篇关于Java Graphics2D AffineTransform 图像旋转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!