first of all, this is the first week that I use swing, then sorry if my question is too obvious. Also, I need solutions that use the standard java libraries, since this is for homework and I'm not allowed to use strange libraries.
I'm using JLabel with ImageIcon to show images on a JFrame. Now I want to rotate the image on screen to arbitrary angles. I found something about Graphics2D but i don't find the way to do that.
Since solutions that I found doesn't work or I don't understand them, I'm interested in any solution to rotate the ImageIcon or the JLabel. Since I'm positioning the image doing setBounds on the JLabel, rotate the JLabel will be a better solution I think (this way I'm not forced to save the ImageIcon object too).
Thank you for your attention and sorry for my bad English.
Edit... To show the image in screen I do the next:
JFrame frame = new JFrame("Something");
frame.setLayout(new FlowLayout()); //for example
JPanel panel = new JPanel();
panel.setLayout(null);
ImageIcon playerSprite = new ImageIcon("rute/to/file.png");
JLabel player = new JLabel(playerSprite);
panel.add(player);
player.setBounds(10,10,36,52); //for example
frame.getContentPane().add(panel);
frame.setVisible(true);
Resuming, how can I rotate this IconImage or the JLabel. I can use other method to show the image if you think that is better. If the solution is use Graphics2D, like I see, I will appreciate a solution to arrive to an object of this class an later return the rotated image to an ImageIcon, because when I try this...
ImageIcon imagePlayer = new ImageIcon("img/stand.png");
Image image = imagePlayer.getImage();
Graphics2D g = (Graphics2D)image.getGraphics();
At execution time, the answer is this...
Exception in thread "main" java.lang.UnsupportedOperationException: getGraphics() not valid for images created with createImage(producer)
2th edition... Now I'm working with this code. The image rotates but the old unrotated image still remains on screen under the new one. Put a png image called stand.png on the same directory and you will see it.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.lang.Math;
public class Test {
public static void main(String args[]) throws Exception {
try {
JFrame frame = new JFrame("Rotation Test");
frame.setBounds(10,10,1008,756);
BufferedImage bi = ImageIO.read(new File("stand.png"));
Graphics2D g = (Graphics2D)bi.getGraphics();
g.rotate(Math.toRadians(45),26,26);
g.drawImage(bi, 0, 0, null);
JLabel player = new JLabel(new ImageIcon(bi));
frame.getContentPane().add(player);
player.setBounds(0,0,100,100);
frame.setVisible(true);
} catch (IOException ex) {
System.out.println("Exception");
}
}
}
Instead of rotating the component itself, consider rotating the content of a component. This example draws a rotated image in a JPanel
.
Addendum: In the example RotatableImage.getImage()
creates a BufferedImage
directly in memory, but you can use ImageIO.read()
to obtain an image from elsewhere. BufferedImage#createGraphics()
is supported if you want to modify the image, but you probably just want to draw the unmodified image in a rotated graphics context as part of paintComponent()
.
Addendum: You're painting over the image with a rotated copy; instead, draw the image into a rotated graphics context:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
public static void main(String args[]) throws Exception {
JFrame frame = new JFrame("Rotation Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final BufferedImage bi = ImageIO.read(new File("img/stand.jpg"));
frame.add(new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(bi.getWidth(), bi.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.rotate(Math.PI / 4, bi.getWidth() / 2, bi.getHeight() / 2);
g2.drawImage(bi, 0, 0, null);
}
});
frame.pack();
frame.setVisible(true);
}
}