GIF ImageIcon 在 Java Swing 中不断闪烁
Posted
技术标签:
【中文标题】GIF ImageIcon 在 Java Swing 中不断闪烁【英文标题】:GIF ImageIcon keeps flickering in Java Swing 【发布时间】:2018-11-03 10:47:55 【问题描述】:我必须在学校用 Java Swing 做一个小游戏。我为它创建了一些 gif,想把它们放进去,我做到了,但问题是 gif 有时会闪烁。我真的在互联网上找不到任何东西,老实说,我什至不知道从哪里开始看。
我的代码:
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class Chicken extends JFrame
private int canvasWidth = 560;
private int canvasHeight = 480;
private Color sideGreen = new Color(14, 37, 14);
private Color gapGreen = new Color(56, 148, 56);
private Color edgeGreen = new Color(49, 129, 49);
private Image chicken;
private Image cookie;
private DrawCanvas canvas;
public Chicken()
canvas = new DrawCanvas();
canvas.setPreferredSize(new Dimension(canvasWidth, canvasHeight));
try
addImages();
catch (Exception ex)
ex.printStackTrace();
Container cp = getContentPane();
cp.add(canvas);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
setTitle("Chicken");
pack();
setVisible(true);
private class DrawCanvas extends JPanel
@Override
public void update(Graphics g)
paintComponent(g);
@Override
public void paintComponent(Graphics g)
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
setDoubleBuffered(true);
setBackground(Color.BLACK);
g2.setColor(sideGreen);
g2.fillRect(0, 0, 80, canvasHeight);
g2.fillRect(canvasWidth - 80, 0, 80, 480);
g2.setColor(gapGreen);
g2.fillRect(80, 0, 400, 100);
g2.fillRect(80, canvasHeight - 100, 400, 100);
g2.setColor(edgeGreen);
g2.fillRect(80, 80, 400, 20);
g2.fillRect(80, canvasHeight - 100, 400, 20);
g2.drawImage(cookie, 85, 5, this);
g2.drawImage(chicken, 150, 120, this);
private void addImages() throws Exception
ImageIcon iconCookie = new ImageIcon(new URL("https://i.stack.imgur.com/1PcWC.gif"));
Image cookieimage = iconCookie.getImage();
Image newimg = cookieimage.getScaledInstance(70, 70, Image.SCALE_DEFAULT);
iconCookie = new ImageIcon(newimg);
ImageIcon iconChicken = new ImageIcon(new URL("https://i.stack.imgur.com/qJA7G.gif"));
Image chickenimage = iconChicken.getImage();
Image newimgc = chickenimage.getScaledInstance(250, 250, Image.SCALE_DEFAULT);
iconChicken = new ImageIcon(newimgc);
chicken = iconChicken.getImage();
cookie = iconCookie.getImage();
public static void main(String[] args)
SwingUtilities.invokeLater(() -> new Chicken());
代码有问题吗?还是有另一种方法可以做到这一点,而我只是做错了? gif 应该没问题,我自己创建的,当我从我的电脑上查看它们时它们看起来很好。
Chicken
Cookie
编辑
取出饼干后发现鸡肉没有闪烁,但我不知道为什么。
【问题讨论】:
@Override public void update(Graphics g)
为什么代码会覆盖该方法?
我将问题中的代码编辑为minimal reproducible example。 (这主要涉及到图像的热链接。)编辑后的代码是否在您的最后显示相同的问题?如果没有,请进入edit history 并回滚我所做的更改。
“我自己创建的..” 就是这样..Image newimgc = chickenimage.getScaledInstance(250, 250, Image.SCALE_DEFAULT);
缩放图像的最佳时间是之前 它们由应用程序加载!
你好@AndrewThompson! @Override public void update(Graphics g)
老实说我不太确定,我们在学校被教导要这样做。还有其他方法吗?还是我应该删除@Override
?我已经尝试过您的更改,但遗憾的是它似乎没有任何区别。还在闪烁。我想我只需将 cookie.gif 更改为似乎可以处理闪烁的 .png。非常感谢您的回答!
“或者我应该删除@Override
吗?” 删除整个方法。改变现有的功能并没有什么好处。当我删除它时,我看不到鸡肉图像中的任何进一步闪烁。我还建议在该代码中进行其他更改,但没有这些更改。
【参考方案1】:
从paintComponent
中删除setDoubleBuffered(true);
。可能是诱人的代码。您可以在构造函数中调用它,但默认情况下双缓冲是打开的。将setBackground(Color.BLACK);
移动到构造函数中。
然后删除update
方法。
您通常不需要致电super.paintComponent();
。将其注释掉,并尝试查看更改。
您可以使用setContentPane(canvas)
。
如果还有问题,那就是gif处理的内部工作原理。
【讨论】:
“您通常不需要致电super.paintComponent();
。” 不过这是最佳做法。
您好!感谢您的答复!我都试过了。当我删除super.paintComponent();
时,它会产生一种奇怪的效果,您可以在背景中看到之前的帧。也很遗憾,它并没有解决闪烁问题,但还是谢谢你!
@AndrewThompson 是的,它负责正确的图形开关。对于闪烁,我想消除它的原因。
@ArvyMinsk 我希望更新重新实现。由于您的评估指向导致闪烁的第二个 gif,也许您应该尝试 JLayeredPane 和/或 OverlayLayout,因此两个双缓冲背景上有两个paintComponents。叹息。
You normally do not need to call super.paintComponent();.
- 您应该始终调用 super.paintComponent() 以确保在进行任何自定义绘画之前清除背景,否则您可能会出现绘画伪影。以上是关于GIF ImageIcon 在 Java Swing 中不断闪烁的主要内容,如果未能解决你的问题,请参考以下文章