I have experienced a bit of a problem with javas rotate method. In the following example, I am first calling the rotate method, drawing the rectangle to be rotated and then calling the rotate method again in the exact opposite direction, therefore painting the following rectangles with a 0 degree rotation. However there seems to be a problem with all things painted afterwards, as the second rectangle experiences something I can only describe as a jitter in the y-axis. This does of course only affect things painted after the rotate method is called. Help would be greatly appreciated, as it really is annoying to look at.
package pack;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Test extends JFrame{
private static final long serialVersionUID = 1L;
public int degrees = 0;
public Timer timer;
public Test() {
setVisible(true);
setSize(400, 400);
setContentPane(new paintLabel());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
timer= new Timer(10, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {degrees++;repaint();}
});
timer.start();
}
public class paintLabel extends JLabel {
private static final long serialVersionUID = 1L;
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.rotate(Math.toRadians(degrees), 100, 185);
g2d.fillRect(40, 125, 120, 120);
g2d.rotate(-Math.toRadians(degrees), 100, 185);
g2d.fillRect(225, 125, 120, 120);
}
}
public static void main(String[] args) {new Test();}
}
This has nothing to do with precision since you are not rotating an image. You are rotating the Graphics context
. The reason the other image didn't rotate is because you simply returned the context to its previous state. You need to then rotate about the center of the second image.
First you were were doing some things incorrectly.
JFrame
(you weren't overriding anything so just use an instance);JPanel
and put that in the FramegetPreferredSize
to size the JLabel
Here try this. If you turn on anti-aliasing the jitter goes away. It also tends to smooth out any rough edges. The other image is rotated in the opposite direction. Note that this could just be done inside of paintComponent
without the JLabel
class.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.renderable.RenderableImage;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Test extends JPanel {
JFrame f = new JFrame();
private static final long serialVersionUID = 1L;
public int degrees = 0;
public Timer timer;
public Test() {
f.add(this);
add(new PaintLabel());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
timer= new Timer(50,(ae)->{degrees++; repaint();});
timer.start();
f.pack();
f.setLocationRelativeTo(null); //center on screen
f.setVisible(true);
}
public class PaintLabel extends JLabel {
private static final long serialVersionUID = 1L;
public Dimension getPreferredSize() {
return new Dimension(400,400);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.BLUE);
g2d.rotate(Math.toRadians(degrees), 100, 185);
g2d.fillRect(40, 125, 120, 120);
g2d.rotate(-Math.toRadians(degrees), 100, 185);
g2d.fillRect(225, 125, 120, 120);
}
}
public static void main(String[] args) {
new Test();}
}