如何解决由于加载图像而导致屏幕闪烁的问题?
Posted
技术标签:
【中文标题】如何解决由于加载图像而导致屏幕闪烁的问题?【英文标题】:How to fix the blinking of the screen due to loading of the Image? 【发布时间】:2019-12-23 21:30:20 【问题描述】:我正在尝试在其上加载和图像绘制,然后将其显示在框架上。 我也可以在框架上加载图像并在框架上绘图,但这会在我的屏幕上产生更多的闪烁。
在下面的代码中,当用户按下任意键时屏幕会闪烁,因为图像被再次加载并且球的新位置被绘制。
if up_key y--
if down_key y++
if left_key x--
if right_key x++
根据按下的键重新显示图像并更新球的位置。
如何减少闪烁效果以使其平滑?
必须替换我在文件构造函数中给出的路径。
import java.awt.*;
import java.io.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
import java.awt.event.*;
class MyFrame extends Frame implements KeyListener
BufferedImage img;
int x=100,y=100;
public MyFrame()
super("Box");
this.setSize(1382,784);
this.setVisible(true);
this.addKeyListener(this);
this.requestFocus();
this.setResizable(false);
public void make()
try
img=ImageIO.read(new File("c:/users/udesh_2/desktop/Boundary.jpg"));
Graphics gfx=img.getGraphics();
gfx.setColor(Color.black);
gfx.fillOval(x,y,40,40);
catch(IOException io)
@Override
public void paint(Graphics g)
make();
g.drawImage(img,0,0,getWidth(),getHeight(),null);
public static void main(String $[])
MyFrame f=new MyFrame();
f.make();
f.repaint();
public void keyPressed(KeyEvent key)
boolean found=false;
if(key.getKeyCode()==KeyEvent.VK_UP)
found=true;
y--;
if(key.getKeyCode()==KeyEvent.VK_DOWN)
found=true;
y++;
if(key.getKeyCode()==KeyEvent.VK_LEFT)
found=true;
x--;
if(key.getKeyCode()==KeyEvent.VK_RIGHT)
found=true;
x++;
if(found)
repaint();
public void keyTyped(KeyEvent key)
public void keyReleased(KeyEvent key)
【问题讨论】:
为避免预加载 img 时闪烁,请将 make() 调用移至构造函数,并避免在 paint 方法中调用 make()。在paint里面你应该只有绘图的东西,而不是加载资源和其他繁重的工作。 @mmmatey 那我应该如何有效地加载加载图像并在框架上显示图像。 我为您准备了如何避免它的示例,现在无法运行,但它应该是这样的:pastebin.com/XpzDx33e 在这里查看代码。 “我想在图像上而不是在框架上绘画” 有趣的是(或者我猜不是),我实际上更喜欢在图像上完成所有绘画,但是它'd 只需使用标签显示(上述第二种方法)。这是an example of doing that,尽管它比您现在看起来需要的要复杂。 我注意到您的代码的一件事。大部分时间都花在了调整图像大小上!如果 GUI 不会改变大小,我只会缩放一次。 (拍前额)并且每次绘制都会调用make()
方法,这会导致图像再次加载!
【参考方案1】:
每次调用repaint()
时,您都在设置变量img
的值,这会导致闪烁。而是在您的构造函数中初始化一次。那么在这种情况下也不需要额外的 make 方法。这应该有效:
import java.awt.*;
import java.io.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
import java.awt.event.*;
class MyFrame extends Frame implements KeyListener
BufferedImage img;
int x = 100, y = 100;
public MyFrame()
super("Box");
this.setSize(480, 480);
this.setVisible(true);
this.addKeyListener(this);
this.requestFocus();
this.setResizable(false);
try
img = ImageIO.read(new File("c:/users/udesh_2/desktop/Boundary.jpg"));
catch (IOException io)
io.printStackTrace();
@Override
public void paint(Graphics g)
super.paint(g);
g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
g.setColor(Color.black);
g.fillOval(x, y, 40, 40);
public static void main(String $[])
MyFrame f = new MyFrame();
f.repaint();
public void keyPressed(KeyEvent key)
boolean found = false;
if (key.getKeyCode() == KeyEvent.VK_UP)
found = true;
y--;
if (key.getKeyCode() == KeyEvent.VK_DOWN)
found = true;
y++;
if (key.getKeyCode() == KeyEvent.VK_LEFT)
found = true;
x--;
if (key.getKeyCode() == KeyEvent.VK_RIGHT)
found = true;
x++;
if (found)
repaint();
public void keyTyped(KeyEvent key)
public void keyReleased(KeyEvent key)
【讨论】:
g.drawImage(img, 0, 0, getWidth(), getHeight(), null);
1) 首先致电super.paint(g);
。 2) Frame
是 ImageObserver
所以 null
最好是 this
。
@AndrewThompson 很好的观察和很好的建议,我已经编辑了我的答案。【参考方案2】:
import java.awt.*;
import java.io.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
import java.awt.event.*;
class MyFrame extends Frame implements KeyListener
BufferedImage img;
Image _img;
Graphics gfx;
int x = 100, y = 100;
public MyFrame()
super("Box");
this.setSize(1000,780);
this.setVisible(true);
this.addKeyListener(this);
this.requestFocus();
this.setResizable(false);
try
img = ImageIO.read(new File("c:/users/udesh_2/desktop/Boundary.jpg"));
catch (IOException io)
io.printStackTrace();
_img=createImage(getWidth(),getHeight());
gfx=_img.getGraphics();
@Override
public void paint(Graphics g)
if(img!=null)
gfx.drawImage((Image)img,0,0,getWidth(),getHeight(),this);
gfx.fillOval(x,y,30,30);
g.drawImage(_img, 0, 0, getWidth(), getHeight(), this);
try
Thread.sleep(70);
catch(Exception e)System.out.println(e);
public static void main(String $[])
MyFrame f = new MyFrame();
f.repaint();
public void keyPressed(KeyEvent key)
boolean found = false;
if (key.getKeyCode() == KeyEvent.VK_UP)
found = true;
y-=2;
if (key.getKeyCode() == KeyEvent.VK_DOWN)
found = true;
y+=2;
if (key.getKeyCode() == KeyEvent.VK_LEFT)
found = true;
x-=2;
if (key.getKeyCode() == KeyEvent.VK_RIGHT)
found = true;
x+=2;
if (found)
repaint();
public void keyTyped(KeyEvent key)
public void keyReleased(KeyEvent key)
【讨论】:
以上是关于如何解决由于加载图像而导致屏幕闪烁的问题?的主要内容,如果未能解决你的问题,请参考以下文章