Search code examples
javaswinggraphics2d

How to rotate something with Graphics2D


So I want to rotate this Rectangle I made

public void paint (Graphics g)
    {
        super.paint(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.fillRect(10, 10, 30, 30);
        g2.rotate(Math.toRadians(45)); //I tried this but doesn't seem to work... 
    }

How do I do that? Rotate as in rotate in 45* angle or 200* angle.


Solution

  • It really isn't that hard to rotate objects. Most of the code below is simply boiler plate to create the frames and panels. Here is a demo that shows two methods that were mentioned in the comments.

    • the left panel simply rotates the graphics context. This is, imo, the easiest method but it does not alter the object.
    • the right panel uses the AffineTransform to rotate the object. This actually changes the contents of the shape.

    If the desire is to rotate an object in place it is necessary to ensure one is rotating about the middle of the image that is under rotation. In both cases below that would be (125,125) or the center of both the panels and the rectangle.

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Polygon;
    import java.awt.RenderingHints;
    import java.awt.Shape;
    import java.awt.geom.AffineTransform;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    import javax.swing.border.LineBorder;
    
    public class RotateRectangle extends JPanel {
        
        JFrame frame = new JFrame();
        double angle = 0;
        MyPanel mypanel = new MyPanel();
        public static void main(String[] args) {
            SwingUtilities
                    .invokeLater(() -> new RotateRectangle().start());
        }
        
        public void start() {
            Timer t = new Timer(0, (ae) -> {mypanel.rotateit(); frame.repaint();});
            t.setDelay(30);
            t.start();
        }
        
        public RotateRectangle() {
            frame.setLayout(new FlowLayout());
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(this);
            frame.add(mypanel);
            setBorder(new LineBorder(Color.red,2));
            mypanel.setBorder(new LineBorder(Color.red, 2));
            frame.pack();
            // center on screen
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
        
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            
            // visually smooth the lines
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            
            g2d.setPaint(Color.BLACK);
            g2d.rotate(angle, 125,125);
            g2d.drawRect(75, 75, 100, 100);
            
    // adjust the amount of rotation per timer interval
            angle += Math.PI / 200;
            g2d.dispose();
        }
        
        public Dimension getPreferredSize() {
            return new Dimension(250, 250);
        }
        
    }
    
    class MyPanel extends JPanel {
        Polygon polygon = new Polygon();
        // amount to rotate
        double angle = Math.PI / 200;
        Shape shape = polygon;
        AffineTransform af =  new AffineTransform();
    
        public MyPanel() {
            af.rotate(angle, 125,125);
            polygon.addPoint(75,175);
            polygon.addPoint(175,175);
            polygon.addPoint(175,75);
            polygon.addPoint(75,75);
    
        }
        public void rotateit() {
            
            shape = af.createTransformedShape(shape);
        
        }
        
        public void paintComponent(Graphics g) {
            if (shape == null) {
                return;
            }
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D)g;
            
            // visually smooth the lines
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            
            g2d.setPaint(Color.BLACK);
            g2d.draw(shape);
            
        }
        
        public Dimension getPreferredSize() {
            return new Dimension(250, 250);
        }
    }