在Java Swing上旋转JLabel或ImageIcon

时间:2023-01-27 20:05:55

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.

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

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.

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

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

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

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...

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

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.

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

2 个解决方案

#1


7  

Instead of rotating the component itself, consider rotating the content of a component. This example draws a rotated image in a JPanel.

不要旋转组件本身,而应考虑旋转组件的内容。此示例在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().

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

#2


3  

Since solutions that I found doesn't work or I don't understand them

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

Well, if you don't understand them, then you should post your SSCCE (http://sscce.org) demonstrating your test code. Then maybe someone will be able to explain how the code work.

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

I doubt you would be able to understand any new code we might post since the concepts of rotation an image or an Icon are all the same.

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

Since I'm positioning the image doing setBounds on the JLabel

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

Why are you using setBounds(). You should use a layout manager so you don't have to worry about this.

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

Edit:

Maybe you can use a Rotated Icon.

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

#1


7  

Instead of rotating the component itself, consider rotating the content of a component. This example draws a rotated image in a JPanel.

不要旋转组件本身,而应考虑旋转组件的内容。此示例在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().

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

#2


3  

Since solutions that I found doesn't work or I don't understand them

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

Well, if you don't understand them, then you should post your SSCCE (http://sscce.org) demonstrating your test code. Then maybe someone will be able to explain how the code work.

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

I doubt you would be able to understand any new code we might post since the concepts of rotation an image or an Icon are all the same.

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

Since I'm positioning the image doing setBounds on the JLabel

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

Why are you using setBounds(). You should use a layout manager so you don't have to worry about this.

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

Edit:

Maybe you can use a Rotated Icon.

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