在Java Swing上旋转JLabel或ImageIcon

首先,这是我使用swing的第一周,如果我的问题太明显,那就很抱歉。 此外,我需要使用标准java库的解决方案,因为这是用于家庭作业,我不允许使用奇怪的库。

我正在使用JLabel和ImageIcon在JFrame上显示图像。 现在我想将屏幕上的图像旋转到任意角度。 我发现了一些关于Graphics2D的东西,但我找不到这样做的方法。

由于我发现的解决方案不起作用或我不理解它,我对旋转ImageIcon或JLabel的任何解决方案感兴趣。 由于我将图像定位在JLabel上的setBounds,旋转JLabel将是一个更好的解决方案我想(这样我也不会被迫保存ImageIcon对象)。

感谢您的关注,抱歉我的英语不好。

编辑…要在屏幕上显示图像,请执行下一步:

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); 

恢复,如何旋转此IconImage或JLabel。 如果您认为更好,我可以使用其他方法来显示图像。 如果解决方案是使用Graphics2D,就像我看到的那样,我将欣赏到达此类对象的解决方案,稍后将旋转后的图像返回到ImageIcon,因为当我尝试这个时……

 ImageIcon imagePlayer = new ImageIcon("img/stand.png"); Image image = imagePlayer.getImage(); Graphics2D g = (Graphics2D)image.getGraphics(); 

在执行时,答案就是这个……

 Exception in thread "main" java.lang.UnsupportedOperationException: getGraphics() not valid for images created with createImage(producer) 

第2版​​……现在我正在使用这段代码。 图像旋转但旧的未旋转图像仍保留在新图像下的屏幕上。 将一个名为stand.png的png图像放在同一目录中,您将看到它。

 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"); } } } 

不要旋转组件本身,而应考虑旋转组件的内容 。 此示例在JPanel绘制旋转图像。

附录:在示例中, RotatableImage.getImage()直接在内存中创建BufferedImage ,但您可以使用ImageIO.read()从其他地方获取图像。 如果要修改图像,则支持BufferedImage#createGraphics() ,但您可能只想在旋转的图形上下文中绘制未修改的图像,作为paintComponent()一部分。

附录:你用旋转的副本在图像上画画; 相反,将图像绘制到旋转的图形上下文中:

 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); } } 

由于我找到的解决方案不起作用或我不理解它们

好吧,如果你不理解它们,那么你应该发布你的SSCCE(http://sscce.org)来演示你的测试代码。 那么也许有人能够解释代码是如何工作的。

我怀疑你能理解我们发布的任何新代码,因为旋转图像或图标的概念都是一样的。

因为我将图像定位在JLabel上的setBounds

你为什么使用setBounds()。 您应该使用布局管理器,这样您就不必担心这一点。

编辑:

也许你可以使用旋转图标 。