JFrame重绘图像闪烁
JFrame repainting image blinking
我在使用命令 super.paintComponents(g) 时遇到问题;更新 JFrame 时。我遇到的问题是我正在加载的图像在代码为 运行 时闪烁。我很确定代码是双缓冲的,并且没有在网上找到任何有用的资源来解决这个问题。这是我的第一个问题,所以请容忍任何格式错误。
这是我的全部代码(下面的片段):
public class GAME extends JFrame implements KeyListener, MouseMotionListener {
int mouseX, mouseY;
public static ArrayList<Images> images = new ArrayList<Images>();
public static String lastKeyPressed = null;
public GAME() {
this.addMouseMotionListener(this);
this.addKeyListener(this);
}
public void mouseDragged(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
}
public void mouseMoved(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == e.VK_LEFT) {
lastKeyPressed = "LEFT";
} else if (e.getKeyCode() == e.VK_RIGHT) {
lastKeyPressed = "RIGHT";
} else if (e.getKeyCode() == e.VK_UP) {
lastKeyPressed = "UP";
} else if (e.getKeyCode() == e.VK_DOWN) {
lastKeyPressed = "DOWN";
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
@Override
public void paint(Graphics g) {
super.paintComponents(g);
for (int i = 0; i < images.size(); i++) {
g.drawImage(images.get(i).img, images.get(i).xpos, images.get(i).ypos, null);
}
}
public static void main(String[] args) throws IOException, InterruptedException {
GAME frame = new GAME();
Dimension dim = new Dimension(800, 600);
frame.setPreferredSize(dim);
frame.setSize(dim);
frame.setResizable(false);
frame.setTitle("GAME");
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Images test = new Images("unnamed.png");
images.add(test);
while (true) {
if (lastKeyPressed == "LEFT") {
test.xpos -= 5;
lastKeyPressed = null;
} else if (lastKeyPressed == "RIGHT") {
test.xpos += 5;
lastKeyPressed = null;
} else if (lastKeyPressed == "UP") {
test.ypos -= 5;
lastKeyPressed = null;
} else if (lastKeyPressed == "DOWN") {
test.ypos += 5;
lastKeyPressed = null;
}
frame.repaint();
Thread.sleep(100);
}
}
}
这是图片 class:
public class Images {
String name;
BufferedImage img;
int xpos;
int ypos;
public Images (String Name) throws IOException{
name = Name;
xpos = 40;
ypos = 90;
System.out.println(name);
System.out.println("PATH: " + GAME.class.getResource(name));
URL file = getClass().getClassLoader().getResource(name);
img = ImageIO.read(file);
}
}
您可能只想看到以下内容:
我的绘画方法:
@Override
public void paint(Graphics g) {
super.paintComponents(g);
for (int i = 0; i < images.size(); i++) {
g.drawImage(images.get(i).img, images.get(i).xpos, images.get(i).ypos, null);
}
}
主要 class 中的代码块,即 运行 游戏:
Images test = new Images("unnamed.png");
images.add(test);
while (true) {
if (lastKeyPressed == "LEFT") {
test.xpos -= 5;
lastKeyPressed = null;
} else if (lastKeyPressed == "RIGHT") {
test.xpos += 5;
lastKeyPressed = null;
} else if (lastKeyPressed == "UP") {
test.ypos -= 5;
lastKeyPressed = null;
} else if (lastKeyPressed == "DOWN") {
test.ypos += 5;
lastKeyPressed = null;
}
frame.repaint();
Thread.sleep(100);
}
(我添加了 Thread.sleep 因为它似乎降低了闪烁发生的速度)
这是正在发生的事情的 gif(我只是使用了 'test' 的第一个 Google 结果作为图像):
http://i.imgur.com/WjLCSvu.gif?1
感谢任何帮助和改进我的代码的一般建议。谢谢。
不要覆盖 paint
顶级容器,例如 JFrame
没有双缓冲,而是使用 JPanel
并覆盖其 paintComponent
方法。 JPanel
默认为双缓冲。
然后,将面板添加到您想要的任何容器中
在进行任何自定义绘画之前,请不要忘记调用它的 super
方法 (super.paintComponent
)。
仔细查看 Painting in AWT and Swing and Performing Custom Painting,了解有关 Swing 绘画工作原理的更多详细信息
这只是您不应该(从 JFrame
扩展并)覆盖顶级容器的 paint
的原因之一,请查看
- How can I set in the midst?
- Graphics rendering in title bar
- Java JFrame .setSize(x, y) not working?
- How to get the EXACT middle of a screen, even when re-sized
还有一些
我在使用命令 super.paintComponents(g) 时遇到问题;更新 JFrame 时。我遇到的问题是我正在加载的图像在代码为 运行 时闪烁。我很确定代码是双缓冲的,并且没有在网上找到任何有用的资源来解决这个问题。这是我的第一个问题,所以请容忍任何格式错误。
这是我的全部代码(下面的片段):
public class GAME extends JFrame implements KeyListener, MouseMotionListener {
int mouseX, mouseY;
public static ArrayList<Images> images = new ArrayList<Images>();
public static String lastKeyPressed = null;
public GAME() {
this.addMouseMotionListener(this);
this.addKeyListener(this);
}
public void mouseDragged(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
}
public void mouseMoved(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == e.VK_LEFT) {
lastKeyPressed = "LEFT";
} else if (e.getKeyCode() == e.VK_RIGHT) {
lastKeyPressed = "RIGHT";
} else if (e.getKeyCode() == e.VK_UP) {
lastKeyPressed = "UP";
} else if (e.getKeyCode() == e.VK_DOWN) {
lastKeyPressed = "DOWN";
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
@Override
public void paint(Graphics g) {
super.paintComponents(g);
for (int i = 0; i < images.size(); i++) {
g.drawImage(images.get(i).img, images.get(i).xpos, images.get(i).ypos, null);
}
}
public static void main(String[] args) throws IOException, InterruptedException {
GAME frame = new GAME();
Dimension dim = new Dimension(800, 600);
frame.setPreferredSize(dim);
frame.setSize(dim);
frame.setResizable(false);
frame.setTitle("GAME");
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Images test = new Images("unnamed.png");
images.add(test);
while (true) {
if (lastKeyPressed == "LEFT") {
test.xpos -= 5;
lastKeyPressed = null;
} else if (lastKeyPressed == "RIGHT") {
test.xpos += 5;
lastKeyPressed = null;
} else if (lastKeyPressed == "UP") {
test.ypos -= 5;
lastKeyPressed = null;
} else if (lastKeyPressed == "DOWN") {
test.ypos += 5;
lastKeyPressed = null;
}
frame.repaint();
Thread.sleep(100);
}
}
}
这是图片 class:
public class Images {
String name;
BufferedImage img;
int xpos;
int ypos;
public Images (String Name) throws IOException{
name = Name;
xpos = 40;
ypos = 90;
System.out.println(name);
System.out.println("PATH: " + GAME.class.getResource(name));
URL file = getClass().getClassLoader().getResource(name);
img = ImageIO.read(file);
}
}
您可能只想看到以下内容:
我的绘画方法:
@Override
public void paint(Graphics g) {
super.paintComponents(g);
for (int i = 0; i < images.size(); i++) {
g.drawImage(images.get(i).img, images.get(i).xpos, images.get(i).ypos, null);
}
}
主要 class 中的代码块,即 运行 游戏:
Images test = new Images("unnamed.png");
images.add(test);
while (true) {
if (lastKeyPressed == "LEFT") {
test.xpos -= 5;
lastKeyPressed = null;
} else if (lastKeyPressed == "RIGHT") {
test.xpos += 5;
lastKeyPressed = null;
} else if (lastKeyPressed == "UP") {
test.ypos -= 5;
lastKeyPressed = null;
} else if (lastKeyPressed == "DOWN") {
test.ypos += 5;
lastKeyPressed = null;
}
frame.repaint();
Thread.sleep(100);
}
(我添加了 Thread.sleep 因为它似乎降低了闪烁发生的速度)
这是正在发生的事情的 gif(我只是使用了 'test' 的第一个 Google 结果作为图像): http://i.imgur.com/WjLCSvu.gif?1
感谢任何帮助和改进我的代码的一般建议。谢谢。
不要覆盖 paint
顶级容器,例如 JFrame
没有双缓冲,而是使用 JPanel
并覆盖其 paintComponent
方法。 JPanel
默认为双缓冲。
然后,将面板添加到您想要的任何容器中
在进行任何自定义绘画之前,请不要忘记调用它的 super
方法 (super.paintComponent
)。
仔细查看 Painting in AWT and Swing and Performing Custom Painting,了解有关 Swing 绘画工作原理的更多详细信息
这只是您不应该(从 JFrame
扩展并)覆盖顶级容器的 paint
的原因之一,请查看
- How can I set in the midst?
- Graphics rendering in title bar
- Java JFrame .setSize(x, y) not working?
- How to get the EXACT middle of a screen, even when re-sized
还有一些