I am trying to display two rotating wheels with diameter 512untis at different rates but i am not able to remove the previous drawn image graphics and set the rotated graphics at the correct position. For now i am doing a rotation with arbitrary angle. I tried affineTransform and got the rotations but it was weird like all pixels spread away. Im using a while loop with thread.sleep(). The following is the code : //The drawSmallCircle and drawBigCircle return two images.
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;
}
}
First rule of Swing. Don't block the Event Dispatching Thread. Doing so will make you application look like it's hung and prevent the EDT from processing any repaint requests.
This means, you need some way to schedule updates that doesn't block the EDT
Second rule of Swing. Don't create or modify any UI component from any thread other then the EDT.
Generally, you should avoid overriding the
paint
method of top level containers likeJFrame
, apart from everything else, they're not double buffered, meaning your painting will flicker as it's updated. Instead, you should use one of theSwing
containers, likeJPanel
There are lots of different ways to achieve this. Basically, here I've used three lists, but if I was serious, I would create an object that could maintain all the required information (image, angle an delta)
In order to achieve the actual animation, I've used a
javax.swing.Timer
. This will trigger an event at least every n periods, but more importantly, it does it within the context of the Event Dispatching Thread. This ensures that all the changes made to the angles are done in way that will prevent any possibility of painting occurring while we're updating the values...This example rotates the three images at different (random) speeds...