paint() 无法绘制 gif 但 png 可以正常工作?
paint() can't draw gif but png works fine?
我正在使用 JLabel 尝试在其上绘制动画 gif 图像。我可以使用构造函数 new JLabel(new ImageIcon(FML.class.getResource("giphy.gif")));
,它会工作得很好,但是当我重写 paint 方法时,它似乎根本不想绘制它。图像不是静止的,它不在那里!我应该提一下,下面显示的两种方法都非常适合 PNG 而不是 GIF。我是不是遗漏了什么或者这是一个 java 错误?
(使用 java 1.8)
编辑:我环顾四周,似乎我并没有完全偏离我需要做的事情,但我遗漏了一些东西。我看过很多帖子 Like this one 但在这种情况下似乎不起作用。
我应该注意到 class 中实际上没有任何其他内容,它只是一个简单的 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);
}
}
}
g.drawImage(image2.getImage(), 64, 64, this);
假设您的图片大小为 64,为什么要在标签边界之外绘制第二张图片?当我将位置更改为 (0, 0) 时,gif 对我来说很好(但我没有使用动画 gif)。
both methods shown below work perfectly fine with a PNG but not a GIF.
我不明白我上面给出的原因。无论如何,你用普通的gif试过吗?
这就是为什么您不应该尝试自己管理这幅画的原因,因为现在您需要担心位置,而对位置进行硬编码并不是一个好的做法。让您的布局管理器为您做这件事。
再问一次,你为什么要这样做。为什么要尝试重写 paint 方法来绘制第二张图像?
相反,您应该这样做:
- 在 paintComponent() 方法中绘制两个图像
- 使用带有
OverlayLayout
的面板,然后您可以将两个标签堆叠在一起。
- 您甚至可以将布局的布局管理器设置为 GridBagLayout 之类的东西,然后当您将 JLabel 添加到标签时,它会自动居中。
//setSize because I want to be 100% sure that it's loading the correct size.
您说您知道布局管理器的工作原理。好吧,如果你这样做了,那么你就知道这个语句不会做任何事情,因为布局管理器会覆盖你设置的任何值,所以使用这样的代码是错误的,并且显示出基本缺乏理解,不应该包含在 MCVE
中,因为MCVE`的重点是尽可能简化问题。
我正在使用 JLabel 尝试在其上绘制动画 gif 图像。我可以使用构造函数 new JLabel(new ImageIcon(FML.class.getResource("giphy.gif")));
,它会工作得很好,但是当我重写 paint 方法时,它似乎根本不想绘制它。图像不是静止的,它不在那里!我应该提一下,下面显示的两种方法都非常适合 PNG 而不是 GIF。我是不是遗漏了什么或者这是一个 java 错误?
(使用 java 1.8)
编辑:我环顾四周,似乎我并没有完全偏离我需要做的事情,但我遗漏了一些东西。我看过很多帖子 Like this one 但在这种情况下似乎不起作用。
我应该注意到 class 中实际上没有任何其他内容,它只是一个简单的 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);
}
}
}
g.drawImage(image2.getImage(), 64, 64, this);
假设您的图片大小为 64,为什么要在标签边界之外绘制第二张图片?当我将位置更改为 (0, 0) 时,gif 对我来说很好(但我没有使用动画 gif)。
both methods shown below work perfectly fine with a PNG but not a GIF.
我不明白我上面给出的原因。无论如何,你用普通的gif试过吗?
这就是为什么您不应该尝试自己管理这幅画的原因,因为现在您需要担心位置,而对位置进行硬编码并不是一个好的做法。让您的布局管理器为您做这件事。
再问一次,你为什么要这样做。为什么要尝试重写 paint 方法来绘制第二张图像?
相反,您应该这样做:
- 在 paintComponent() 方法中绘制两个图像
- 使用带有
OverlayLayout
的面板,然后您可以将两个标签堆叠在一起。 - 您甚至可以将布局的布局管理器设置为 GridBagLayout 之类的东西,然后当您将 JLabel 添加到标签时,它会自动居中。
//setSize because I want to be 100% sure that it's loading the correct size.
您说您知道布局管理器的工作原理。好吧,如果你这样做了,那么你就知道这个语句不会做任何事情,因为布局管理器会覆盖你设置的任何值,所以使用这样的代码是错误的,并且显示出基本缺乏理解,不应该包含在 MCVE
中,因为MCVE`的重点是尽可能简化问题。