title: Rotate what is painted in a JPanel keeping the centroid's location
body: <p>I want to rotate what is painted in a <code>paintComponent(Graphics g)</code> method according to a rotation angle and around the centroid of the corresponding panel.</p>
  
  <p>Here's what I have initially:</p>
  
  <p><img src="https://i.stack.imgur.com/Dise7.png" alt="Initial state"></p>
  
  <p>A control panel (textfield + button) to set the angle (in degrees, from 0 to 359). A main panel containing a little white panel. The little white panel has to be updated (<code>setBounds()</code> and <code>repaint()</code>) when the user clicks on the "Set angle" button. In any case the little white panel has to be centered on its centroid.</p>
  
  <p>Here's what I want for 90 and 135 degrees:</p>
  
  <p><img src="https://i.stack.imgur.com/WGCMc.png" alt="90 degrees state"></p>
  
  <p><img src="https://i.stack.imgur.com/lkqis.png" alt="135 degrees state"></p>
  
  <p>Here's my SSCCE (which is not working). Could you tell me what I'm doing wrong?</p>
  
  <pre><code>import java.awt.BorderLayout;
  import java.awt.Color;
  import java.awt.Dimension;
  import java.awt.Graphics;
  import java.awt.Graphics2D;
  import java.awt.Point;
  import java.awt.Rectangle;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.util.ArrayList;
  import java.util.List;
  import javax.swing.JButton;
  import javax.swing.JFrame;
  import javax.swing.JPanel;
  import javax.swing.JTextField;
  
  public class RotatingPaint {
      private static double angle = 0;
      private static JFrame frame = new JFrame();
      private static JTextField angleField = new JTextField("0", 6);
      private static JButton angleButton = new JButton("Set angle");
      private static JPanel controlPanel = new JPanel();
      private static JPanel mainPanel  = new JPanel();
      private static JPanel littleWhitePanel  = new JPanel() {
          @Override
          protected void paintComponent(Graphics g)
          {
              super.paintComponent(g);
              Graphics2D g2 = (Graphics2D) g;
              Color oldColor = g2.getColor();
              g2.setColor(Color.RED);
              g2.rotate(angle, getWidth() / 2, getHeight() / 2);
              g2.drawString("Hello World", 2, 12);
              // Revert the transformation matrix back to its initial state
              g2.rotate(-angle, -getWidth() / 2, -getHeight() / 2);
              g2.setColor(oldColor);
          }
      };
  
  
      public RotatingPaint() {
  
          // Inits control panel
          angleButton.addActionListener(new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent e){
                  angle = Math.toRadians(Integer.parseInt(angleField.getText()));
                  Rectangle oldBounds = littleWhitePanel.getBounds();
                  Rectangle newBounds = getBoundsOfRotatedRectangle(oldBounds);
                  littleWhitePanel.setBounds(newBounds);
                  mainPanel.repaint();
              }
          });
          controlPanel.add(angleField);
          controlPanel.add(angleButton);
  
          // Inits main panel
          mainPanel.setPreferredSize(new Dimension(400, 300));
          mainPanel.setLayout(null);
          littleWhitePanel.setBounds(160, 100, 80, 20);
          littleWhitePanel.setBackground(Color.WHITE);
          mainPanel.add(littleWhitePanel);
  
          // Inits frame
          frame.setLayout(new BorderLayout());
          frame.add(controlPanel, BorderLayout.NORTH);
          frame.add(mainPanel, BorderLayout.CENTER);
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.pack();
          frame.setVisible(true);
      }
  
      public static void main(String[] args) {
          RotatingPaint app = new RotatingPaint();
      }
  
      /**
       * Applies the rotate transformation to a Point.
       * @param point the point to be rotated
       */
      private void rotatePoint(Point point) {
          Point centroid = new Point((int) littleWhitePanel.getBounds().getCenterX(), (int) littleWhitePanel.getBounds().getCenterY());
          int x = (int) Math.rint(centroid.x
                  + (point.x - centroid.x) * Math.cos(angle)
                  - (point.y - centroid.y) * Math.sin(angle));
          int y = (int) Math.rint(centroid.y
                  + (point.x - centroid.x) * Math.sin(angle)
                  + (point.y - centroid.y) * Math.cos(angle));
          point.x = x;
          point.y = y;
      }
  
      /**
       * @param rectangle the rectangle to be rotated
       * @return the bounding rectangle of the rotated rectangle
       */
      private Rectangle getBoundsOfRotatedRectangle(Rectangle rectangle) {
  
          // Getting each corner
          List&lt;Point&gt; corners = new ArrayList&lt;Point&gt;();
          Point topLeftCorner = rectangle.getLocation();
          corners.add(topLeftCorner);
          Point topRightCorner = new Point(topLeftCorner);
          topRightCorner.x += rectangle.width;
          corners.add(topRightCorner);
          Point bottomLeftCorner = new Point(topLeftCorner);
          bottomLeftCorner.y += rectangle.height;
          corners.add(bottomLeftCorner);
          Point bottomRightCorner = new Point(bottomLeftCorner);
          bottomRightCorner.x += rectangle.width;
          corners.add(bottomRightCorner);
  
          // Transforming each corner
          for (Point corner : corners) {
              rotatePoint(corner);
          }
  
          // Getting the min/max x and the min/max y
          int minX = corners.get(0).x;
          int minY = corners.get(0).y;
          int maxX = corners.get(0).x;
          int maxY = corners.get(0).y;
          for (int i = 1; i &lt; corners.size(); i++) {
              minX = Math.min(minX, corners.get(i).x);
              minY = Math.min(minY, corners.get(i).y);
              maxX = Math.max(maxX, corners.get(i).x);
              maxY = Math.max(maxY, corners.get(i).y);
          }
  
          return new Rectangle(minX, minY, maxX - minX, maxY - minY);
      }
  }
  </code></pre>
  
  <p>I manage to reset the bounds of the little white panel but I'm not able to rotate the text correctly. It's pretty hard to describe what isn't working precisely. Please execute that code and check by yourself.</p>
  
  <p>Thank you.</p>