【发布时间】:2018-02-20 09:18:26
【问题描述】:
我正在使用 JLabel 尝试在其上绘制动画 gif 图像。我可以使用构造函数new JLabel(new ImageIcon(FML.class.getResource("giphy.gif")));,它会工作得很好,但是当我重写paint方法时,它似乎根本不想绘制它。图像不是静止的,它不存在!我应该提一下,下面显示的两种方法都适用于 PNG 但不适用于 GIF。我错过了什么还是这是一个java错误?
(使用 java 1.8)
编辑:我一直在环顾四周,似乎我并没有完全偏离我需要做的事情,但我错过了一些东西。我看过很多帖子Like this one,但在这种情况下似乎不起作用。
我应该注意,课堂上实际上没有其他内容,它是一个简单的 JPanel。
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class FML {
public static void main(String[] args) {
new FML();
}
public FML() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private ImageIcon animatedGif;
public TestPane() {
setLayout(new GridBagLayout());
JButton btn = new JButton(new ImageIcon(FML.class.getResource("FmDxW.png")));
btn.setSize(50, 50);
btn.setRolloverEnabled(true);
animatedGif = new ImageIcon(FML.class.getResource("giphy.gif"));
btn.setRolloverIcon(animatedGif);
add(btn);
btn.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
animatedGif.getImage().flush();
}
});
//I need this
final ImageIcon image = new ImageIcon(FML.class.getResource("giphy.gif"));
//To render over this
final ImageIcon image2 = new ImageIcon(FML.class.getResource("fmDxW.png"));
//I'm not understanding why I can add the gif into the constructor but the paint method fails.
JLabel label = new JLabel(image) {
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(image2.getImage(), 64, 64, this);
}
};
//setSize because I want to be 100% sure that it's loading the correct size.
//Removing it doesn't affect the problem at hand.
label.setSize(64, 64);
add(label);
}
}
}
【问题讨论】:
-
1) 您不应该在绘画方法中进行 I/O。 2) 自定义绘画(需要时)是通过覆盖paintComponent(...) 来完成的。 3)无需自定义绘制,只需在JLabel中添加一个Icon即可。 4) 不要在标签上使用 setSize(...)。这意味着您使用的是空布局。不要使用空布局。 Swing 旨在与布局管理器一起使用。阅读 Swing tutorial 了解 Swing 基础知识。有关于使用图标和自定义绘画的部分。
-
这只是测试代码,我永远不会在生产代码上使用 IO。话虽如此,在我的具体实现中确实需要自定义绘画。尽管如此,我还是尝试将 IO 移出渲染循环,因为这可能是问题所在,但没有骰子。问题依然存在。 -edit- 再次,这是测试代码,我知道如何使用布局管理器和自定义绘画并不复杂。我觉得我只是错过了一些具体的东西。
-
如果您知道如何使用布局管理器并进行自定义绘画,那么您应该没有问题,为什么要覆盖paint()?。但显然你确实有问题。我不知道您为什么要扩展 JLabel 以进行自定义绘画,以简单地尝试绘制图像。 JLabel 无需任何自定义即可为您执行此操作。我看到的所有代码都表明您不了解 Swing 的基础知识。发布正确的minimal reproducible example,使用正确的 Swing 技术演示问题。
-
在那里,我已经包含了整个班级并添加了 cmets 来帮助解释我正在尝试做的事情。
标签: java swing rendering paint gif