JLabel中的Java旋转图标

JLabel中的Java旋转图标,java,image,rotation,icons,jlabel,Java,Image,Rotation,Icons,Jlabel,嗨,我在尝试旋转JLabel内的图像时遇到问题。我从StackOverflow中得到了这段代码,我试图对它进行一点修改,以使图像在选项卡中旋转,而不是在JLabel中旋转 公共类ProgressTabbedPane{ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() {

嗨,我在尝试旋转JLabel内的图像时遇到问题。我从StackOverflow中得到了这段代码,我试图对它进行一点修改,以使图像在选项卡中旋转,而不是在JLabel中旋转

公共类ProgressTabbedPane{

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            JFrame frame = new JFrame("RotatingIcon"); 
            JTabbedPane tabbedPane = new JTabbedPane();
            JLabel lable = new JLabel();



            tabbedPane.addTab("Searching", new RotatingIcon(new ImageIcon("disk.png"), tabbedPane, 10), new JLabel( /*new ImageIcon( "resources/images/rotatingIcon.gif" )*/));               
            frame.getContentPane().add(tabbedPane);                
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            //frame.setUndecorated(true);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);

        }
    });
}

private static class RotatingIcon implements Icon {

    private final Icon delegateIcon;
    private double angleInDegrees = 90;
    final private Timer rotatingTimer;

    private RotatingIcon(Icon icon, final JComponent component, int vrotating) {
        delegateIcon = icon;
        rotatingTimer = new Timer(vrotating, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                angleInDegrees = angleInDegrees + 1;
                if (angleInDegrees == 360) {
                    angleInDegrees = 0;
                }
                component.repaint();

            }
        });
        rotatingTimer.setRepeats(false);
        rotatingTimer.start();

    }

    @Override
    public void paintIcon(Component c, Graphics g, int x, int y) {
        rotatingTimer.stop();
        Graphics2D g2 = (Graphics2D) g.create();
        int cWidth = delegateIcon.getIconWidth() / 2;
        int cHeight = delegateIcon.getIconHeight() / 2;
        Rectangle r = new Rectangle(x, y, delegateIcon.getIconWidth(), delegateIcon.getIconHeight());
        g2.setClip(r);
        AffineTransform original = g2.getTransform();
        AffineTransform at = new AffineTransform();
        at.concatenate(original);
        at.rotate(Math.toRadians(angleInDegrees), x + cWidth, y + cHeight);
        g2.setTransform(at);
        delegateIcon.paintIcon(c, g2, x, y);
        g2.setTransform(original);
        rotatingTimer.start();
    }

    @Override
    public int getIconWidth() {
        return delegateIcon.getIconWidth();
    }

    @Override
    public int getIconHeight() {
        return delegateIcon.getIconHeight();
    }
}
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            JFrame frame = new JFrame("RotatingIcon"); 
            JTabbedPane tabbedPane = new JTabbedPane();
            JLabel lable = new JLabel();




            lable.setIcon(new RotatingIcon(new ImageIcon(disk.png"), tabbedPane, 10));                
            frame.getContentPane().add(lable);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            //frame.setUndecorated(true);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);

        }
    });
}

private static class RotatingIcon implements Icon {

    private final Icon delegateIcon;
    private double angleInDegrees = 90;
    final private Timer rotatingTimer;

    private RotatingIcon(Icon icon, final JComponent component, int vrotating) {
        delegateIcon = icon;
        rotatingTimer = new Timer(vrotating, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                angleInDegrees = angleInDegrees + 1;
                if (angleInDegrees == 360) {
                    angleInDegrees = 0;
                }
                component.repaint();

            }
        });
        rotatingTimer.setRepeats(false);
        rotatingTimer.start();

    }

    @Override
    public void paintIcon(Component c, Graphics g, int x, int y) {
        rotatingTimer.stop();
        Graphics2D g2 = (Graphics2D) g.create();
        int cWidth = delegateIcon.getIconWidth() / 2;
        int cHeight = delegateIcon.getIconHeight() / 2;
        Rectangle r = new Rectangle(x, y, delegateIcon.getIconWidth(), delegateIcon.getIconHeight());
        g2.setClip(r);
        AffineTransform original = g2.getTransform();
        AffineTransform at = new AffineTransform();
        at.concatenate(original);
        at.rotate(Math.toRadians(angleInDegrees), x + cWidth, y + cHeight);
        g2.setTransform(at);
        delegateIcon.paintIcon(c, g2, x, y);
        g2.setTransform(original);
        rotatingTimer.start();
    }

    @Override
    public int getIconWidth() {
        return delegateIcon.getIconWidth();
    }

    @Override
    public int getIconHeight() {
        return delegateIcon.getIconHeight();
    }
}
} 这正在工作,图像正在旋转。 但是当我把它改成这个的时候

公共类ProgressTabbedPane{

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            JFrame frame = new JFrame("RotatingIcon"); 
            JTabbedPane tabbedPane = new JTabbedPane();
            JLabel lable = new JLabel();



            tabbedPane.addTab("Searching", new RotatingIcon(new ImageIcon("disk.png"), tabbedPane, 10), new JLabel( /*new ImageIcon( "resources/images/rotatingIcon.gif" )*/));               
            frame.getContentPane().add(tabbedPane);                
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            //frame.setUndecorated(true);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);

        }
    });
}

private static class RotatingIcon implements Icon {

    private final Icon delegateIcon;
    private double angleInDegrees = 90;
    final private Timer rotatingTimer;

    private RotatingIcon(Icon icon, final JComponent component, int vrotating) {
        delegateIcon = icon;
        rotatingTimer = new Timer(vrotating, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                angleInDegrees = angleInDegrees + 1;
                if (angleInDegrees == 360) {
                    angleInDegrees = 0;
                }
                component.repaint();

            }
        });
        rotatingTimer.setRepeats(false);
        rotatingTimer.start();

    }

    @Override
    public void paintIcon(Component c, Graphics g, int x, int y) {
        rotatingTimer.stop();
        Graphics2D g2 = (Graphics2D) g.create();
        int cWidth = delegateIcon.getIconWidth() / 2;
        int cHeight = delegateIcon.getIconHeight() / 2;
        Rectangle r = new Rectangle(x, y, delegateIcon.getIconWidth(), delegateIcon.getIconHeight());
        g2.setClip(r);
        AffineTransform original = g2.getTransform();
        AffineTransform at = new AffineTransform();
        at.concatenate(original);
        at.rotate(Math.toRadians(angleInDegrees), x + cWidth, y + cHeight);
        g2.setTransform(at);
        delegateIcon.paintIcon(c, g2, x, y);
        g2.setTransform(original);
        rotatingTimer.start();
    }

    @Override
    public int getIconWidth() {
        return delegateIcon.getIconWidth();
    }

    @Override
    public int getIconHeight() {
        return delegateIcon.getIconHeight();
    }
}
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            JFrame frame = new JFrame("RotatingIcon"); 
            JTabbedPane tabbedPane = new JTabbedPane();
            JLabel lable = new JLabel();




            lable.setIcon(new RotatingIcon(new ImageIcon(disk.png"), tabbedPane, 10));                
            frame.getContentPane().add(lable);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            //frame.setUndecorated(true);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);

        }
    });
}

private static class RotatingIcon implements Icon {

    private final Icon delegateIcon;
    private double angleInDegrees = 90;
    final private Timer rotatingTimer;

    private RotatingIcon(Icon icon, final JComponent component, int vrotating) {
        delegateIcon = icon;
        rotatingTimer = new Timer(vrotating, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                angleInDegrees = angleInDegrees + 1;
                if (angleInDegrees == 360) {
                    angleInDegrees = 0;
                }
                component.repaint();

            }
        });
        rotatingTimer.setRepeats(false);
        rotatingTimer.start();

    }

    @Override
    public void paintIcon(Component c, Graphics g, int x, int y) {
        rotatingTimer.stop();
        Graphics2D g2 = (Graphics2D) g.create();
        int cWidth = delegateIcon.getIconWidth() / 2;
        int cHeight = delegateIcon.getIconHeight() / 2;
        Rectangle r = new Rectangle(x, y, delegateIcon.getIconWidth(), delegateIcon.getIconHeight());
        g2.setClip(r);
        AffineTransform original = g2.getTransform();
        AffineTransform at = new AffineTransform();
        at.concatenate(original);
        at.rotate(Math.toRadians(angleInDegrees), x + cWidth, y + cHeight);
        g2.setTransform(at);
        delegateIcon.paintIcon(c, g2, x, y);
        g2.setTransform(original);
        rotatingTimer.start();
    }

    @Override
    public int getIconWidth() {
        return delegateIcon.getIconWidth();
    }

    @Override
    public int getIconHeight() {
        return delegateIcon.getIconHeight();
    }
}
}

如果这是一个愚蠢的问题,我很抱歉,但我似乎找不到答案


谢谢你

绘画方法只能用于绘画。它不应该停止/启动计时器。所以我猜您需要从绘画方法中去掉计时器逻辑,然后将计时器设置为重复,以便生成连续事件

有关其他方法,请查看

动画图标
将保存一个图标列表,以便根据计时器顺序显示。当定时器触发时,显示循环中的下一个图标。可以将动画配置为连续,也可以指定显示每个图标的循环数

注意:这个解决方案应该更有效,因为它只重新绘制图标,而不是整个组件

如果您不喜欢为动画创建所有图标,则可以使用。使用此类可以设置图标的旋转度。然后计时器与类完全分离。然后,当定时器代码触发时,您将增加旋转角度

使用
AnimatedIcon
的简单示例:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class SSCCE extends JPanel
{
    public SSCCE()
    {
        setLayout( new BorderLayout() );

        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.add("1", new JPanel());
        tabbedPane.add("2", new JPanel());
        add(tabbedPane);

        AnimatedIcon icon = new AnimatedIcon(tabbedPane, 250, 3);
        ImageIcon duke = new ImageIcon( "copy16.gif" );
        icon.addIcon( duke );

        for (int angle = 30; angle < 360; angle += 30)
        {
            icon.addIcon( new RotatedIcon(duke, angle) );
        }

        tabbedPane.setIconAt(0, icon);
        icon.start();
    }


    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SSCCE());
        frame.setLocationByPlatform( true );
        frame.pack();
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater( () -> createAndShowGUI() );
/*
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
*/
    }
}
import java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
公共类SSCCE扩展了JPanel
{
公共服务
{
setLayout(新的BorderLayout());
JTabbedPane tabbedPane=新的JTabbedPane();
添加(“1”,新JPanel());
添加(“2”,新JPanel());
添加(选项卡窗格);
AnimatedIcon图标=新的AnimatedIcon(选项卡窗格,250,3);
ImageIcon duke=新的ImageIcon(“copy16.gif”);
爱迪肯(杜克);
用于(内部角度=30;角度<360;角度+=30)
{
图标addIcon(新RotatedIcon(杜克,安格尔));
}
tabbedPane.setIconAt(0,图标);
icon.start();
}
私有静态void createAndShowGUI()
{
JFrame=新JFrame(“SSCCE”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(新的SSCCE());
frame.setLocationByPlatform(真);
frame.pack();
frame.setVisible(true);
}
公共静态void main(字符串[]args)
{
invokeLater(()->createAndShowGUI());
/*
invokeLater(新的Runnable()
{
公开募捐
{
createAndShowGUI();
}
});
*/
}
}

它似乎只工作了两圈,然后就停止工作了。我不确定您是否要重复停止/start我确实尝试了您的建议,尽管图像没有旋转。不知道为什么,我从页面复制了代码。@Puzzero,请参见编辑。也许你忘了启动动画?当你说有些事情不管用时,别忘了发帖子。我们无法猜测您的代码可能是什么。我设法让其他代码正常工作,但我想使用您的解决方案。我不知道我在哪里没有实现它,我让你的代码运行,谢谢!,不过它似乎比我的跑得慢。我让我的另一个代码工作。@Puzzero,
它似乎比我的运行得慢。
您可以将计时器速度配置为您想要的任何速度。你的示例代码是10,我的示例代码是250。