旋转后java图像不在正确位置(图形)
我试图以不同的速率显示两个直径为512untis的旋转车轮,但我无法删除以前绘制的图像图形并将旋转的图形设置在正确的位置。 现在我正在做一个任意角度的旋转。 我尝试了仿射变换,得到了旋转,但奇怪的是所有的像素都散开了。 我正在使用一个while循环和线程。睡眠()。代码如下: //drawSmallCircle和drawBigCircle返回两个图像
class MyFramePart2 extends JFrame
{
String name;
JPanel big_obj_panel,small_obj_panel;
JLabel bigLabel,smallLabel;BufferedImage imgRet,imgRetSmall;
static double radians,angle,rev,fps,smallAngle,smallRadians;
int numLines,i=0;
MyFramePart2(String frameName,int numStrokes,double revolutions,double frameps)
{
numLines=numStrokes;
smallAngle=smallRadians=angle=radians=Math.toRadians(360/numLines);
rev=revolutions;
fps=frameps;
setSize(1240,720);
setLocation(0,0);
setLayout(null);
getContentPane().setBackground(Color.WHITE);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
big_obj_panel=new JPanel();
big_obj_panel.setLayout(null);
big_obj_panel.setSize(512,512);
big_obj_panel.setLocation(100,100);
big_obj_panel.setBackground(Color.white);
add(big_obj_panel);
imgRet=drawBigCircle();
bigLabel = new JLabel(new ImageIcon(imgRet));
bigLabel.setLayout(null);
bigLabel.setLocation(0,0);
bigLabel.setSize(512,512);
bigLabel.setOpaque(true);
bigLabel.setBackground(Color.white);
big_obj_panel.add(bigLabel);
small_obj_panel=new JPanel();
small_obj_panel.setLayout(null);
small_obj_panel.setSize(512,512);
small_obj_panel.setLocation(700,100);
small_obj_panel.setBackground(Color.white);
add(small_obj_panel);
imgRetSmall=drawSmallCircle();
smallLabel = new JLabel(new ImageIcon(imgRetSmall));
smallLabel.setLayout(null);
smallLabel.setLocation(0,0);
smallLabel.setSize(512,512);
smallLabel.setOpaque(true);
smallLabel.setBackground(Color.white);
small_obj_panel.add(smallLabel);
setVisible(true);
while(i!=5) // suppose to be while true, just checking
{
setVisible(true);
bigLabel.setIcon(new ImageIcon(imgRet));
smallLabel.setIcon(new ImageIcon(imgRetSmall));
try{
Thread.sleep(10);
}
catch(Exception e)
{}
i++;
}
}
@Override
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2d=(Graphics2D)g;
g2d.translate(256,256);
g2d.rotate(Math.toRadians(20));
g2d.translate(-256,-256);
g2d.drawImage(imgRet,0,0,null);
g2d.dispose();
super.paint(g);
g2d=(Graphics2D)g;
g2d.translate(256,256);
g2d.rotate(Math.toRadians(30));
g2d.translate(-256,-256);
g2d.drawImage(imgRetSmall,0,0,null);
g2d.dispose();
}
public static BufferedImage drawBigCircle()
{
BufferedImage img=new BufferedImage(512,512,BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d=img.createGraphics();
g2d.setColor(Color.black);
g2d.drawOval(0,0,511,511);
Line2D l2d;
while(angle <= 2*Math.PI)
{
l2d=new Line2D.Double(256,256,256+256*Math.cos(angle),256+256*Math.sin(angle));
g2d.draw(l2d);
angle=angle+radians;
}
return img;
}
}
# 1 楼答案
挥杆的第一条规则。不要阻止事件调度线程。这样做会使应用程序看起来像挂起了一样,并阻止EDT处理任何重新绘制请求
这意味着,您需要某种方式来安排不阻止EDT的更新
第二条挥杆规则。不要从EDT以外的任何线程创建或修改任何UI组件
通常,您应该避免覆盖顶级容器(如
JFrame
)的paint
方法,除此之外,它们不是双缓冲的,这意味着您的绘画在更新时会闪烁。相反,您应该使用一个Swing
容器,如JPanel
有很多不同的方法来实现这一点。基本上,这里我使用了三个列表,但如果我是认真的,我会创建一个可以维护所有必需信息的对象(图像、角度和三角形)
为了实现实际的动画,我使用了
javax.swing.Timer
。这将至少每隔n时段触发一个事件,但更重要的是,它在事件调度线程的上下文中触发。这确保了对角度所做的所有更改都是以这样的方式进行的,即在我们更新值时,防止出现任何绘制的可能性此示例以不同(随机)速度旋转三个图像