Java JLabel 中的旋转图标
Java Rotating Icon in JLabel
您好,我在尝试旋转 JLabel 内的图像时遇到问题。我从 Whosebug 获得这段代码,我试图稍微改变它,以便在 Tab 中旋转的图像在 JLabel 中旋转。
public class 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 class 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();
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();
}
}
}
这停止工作,如果这是一个愚蠢的问题,我很抱歉,但我似乎找不到答案。
谢谢
一种画法,只能用来画东西。它不应该 stop/start 一个定时器。所以我猜想你需要从绘画方法中去掉定时器逻辑,然后将定时器设置为重复,以便生成连续的事件。
有关替代方法,请查看 Animated Icon。
Animated Icon
将保存一个图标列表,以根据计时器顺序显示。当计时器触发循环中的下一个图标时,将显示。您可以将动画配置为连续播放或指定循环显示每个图标的次数。
注意:此解决方案应该更有效,因为它只重绘图标,而不是整个组件。
如果您不喜欢为动画创建所有图标的想法,那么您可以使用 Rotated Icon。使用此 class 您可以设置图标的旋转度数。然后 Timer 与 class 完全分离。然后,当定时器代码触发时,您将增加旋转度数。
使用 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();
}
});
*/
}
}
您好,我在尝试旋转 JLabel 内的图像时遇到问题。我从 Whosebug 获得这段代码,我试图稍微改变它,以便在 Tab 中旋转的图像在 JLabel 中旋转。
public class 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 class 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();
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();
}
}
}
这停止工作,如果这是一个愚蠢的问题,我很抱歉,但我似乎找不到答案。
谢谢
一种画法,只能用来画东西。它不应该 stop/start 一个定时器。所以我猜想你需要从绘画方法中去掉定时器逻辑,然后将定时器设置为重复,以便生成连续的事件。
有关替代方法,请查看 Animated Icon。
Animated Icon
将保存一个图标列表,以根据计时器顺序显示。当计时器触发循环中的下一个图标时,将显示。您可以将动画配置为连续播放或指定循环显示每个图标的次数。
注意:此解决方案应该更有效,因为它只重绘图标,而不是整个组件。
如果您不喜欢为动画创建所有图标的想法,那么您可以使用 Rotated Icon。使用此 class 您可以设置图标的旋转度数。然后 Timer 与 class 完全分离。然后,当定时器代码触发时,您将增加旋转度数。
使用 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();
}
});
*/
}
}