How to rotate an image gradually in Swing?

前端 未结 3 1639
眼角桃花
眼角桃花 2020-11-22 07:59

I have an image I am rotating when the user clicks on a button. But it is not working.

I would like to see the image rotating gradually to 90 degrees till it stops b

3条回答
  •  名媛妹妹
    2020-11-22 08:53

    In addition to @tulskiy's helpful observations, I would add two points:

    1. Always construct your GUI on the event dispatch thread, as shown below.

    2. An sscce should be a Short, Self Contained, Correct (Compilable), Example. As a convenience, don't require others to recreate multiple public classes; use top-level (package-private) or nested classes. As this is a graphics problem, use a public or synthetic image that reflects your problem.

    In the example below, paintComponent() alters the graphics context's transform to effect the rotation. Note that the operations are performed in the (apparent) reverse of the declaration order: First, the image's center is translated to the origin; second, the image is rotated; third, the image's center is translated to the center of the panel. You can see the effect by resizing the panel.

    Addendum: See also this alternative approach using AffineTransform.

    image

    package overflow;
    
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.BufferedImage;
    import java.util.Random;
    import javax.swing.*;
    
    /**
     * @see https://stackoverflow.com/questions/3371227
     * @see https://stackoverflow.com/questions/3405799
     */
    public class RotateApp {
    
        private static final int N = 3;
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    JFrame frame = new JFrame();
                    frame.setLayout(new GridLayout(N, N, N, N));
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    for (int i = 0; i < N * N; i++) {
                        frame.add(new RotatePanel());
                    }
                    frame.pack();
                    frame.setVisible(true);
                }
            });
        }
    }
    
    
    class RotatePanel extends JPanel implements ActionListener {
    
        private static final int SIZE = 256;
        private static double DELTA_THETA = Math.PI / 90;
        private final Timer timer = new Timer(25, this);
        private Image image = RotatableImage.getImage(SIZE);
        private double dt = DELTA_THETA;
        private double theta;
    
        public RotatePanel() {
            this.setBackground(Color.lightGray);
            this.setPreferredSize(new Dimension(
                image.getWidth(null), image.getHeight(null)));
            this.addMouseListener(new MouseAdapter() {
    
                @Override
                public void mousePressed(MouseEvent e) {
                    image = RotatableImage.getImage(SIZE);
                    dt = -dt;
                }
            });
            timer.start();
        }
    
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.translate(this.getWidth() / 2, this.getHeight() / 2);
            g2d.rotate(theta);
            g2d.translate(-image.getWidth(this) / 2, -image.getHeight(this) / 2);
            g2d.drawImage(image, 0, 0, null);
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            theta += dt;
            repaint();
        }
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(SIZE, SIZE);
        }
    
    }
    
    class RotatableImage {
    
        private static final Random r = new Random();
    
        static public Image getImage(int size) {
            BufferedImage bi = new BufferedImage(
                size, size, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = bi.createGraphics();
            g2d.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setPaint(Color.getHSBColor(r.nextFloat(), 1, 1));
            g2d.setStroke(new BasicStroke(size / 8));
            g2d.drawLine(0, size / 2, size, size / 2);
            g2d.drawLine(size / 2, 0, size / 2, size);
            g2d.dispose();
            return bi;
        }
    }
    

提交回复
热议问题