Java repaint() 方法并不总是有效 [英] Java repaint() method doesn't always work
问题描述
Java 中的 repaint() 方法有问题.我创建了一个不断重绘屏幕的新线程.当我释放空格键时,我希望我的播放器通过设置它的位置然后等待 50 毫秒并循环 20 次来平稳下降.相反,它在循环中等待全部时间,然后重新绘制.我想知道为什么它不不断地重新绘制玩家坐标的变化.谢谢.
There is a problem with the repaint() method in Java. I made a new thread that constantly repaints the screen. When I release the spacebar I want my player to fall smoothly by setting its position and then waiting for 50 milliseconds and looping that 20 times. Instead, it waits the whole amount of time in the loop, then repaints. I am wondering why it doesn't constantly repaint the changes in the players co-ordinates. Thank you.
(编辑)感谢大家的帮助.这是我第一次使用堆栈溢出,我才 13 岁,还在学习 Java,所以我可能会再次回到教程中.
(Edit) Thanks everyone for the help. This is my first time using stack overflow, and I am only 13 and still learning java, so I probably will go back to the tutorials again.
我的'a'类(主要):
My 'a' class (main):
public class a {
public static void main(String[] args) {
JFrame frame = new JFrame("StickFigure Game");
frame.setSize(740, 580);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
b board = new b();
frame.add(board);
frame.addKeyListener(board);
}
}
我的b"类(JPanel/绘图):
My 'b' class (JPanel/drawing):
public class b extends JPanel implements KeyListener {
c player = new c();
public class MyRunnable implements Runnable {
public void run() {
while (true)
repaint();
}
}
MyRunnable run = new MyRunnable();
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(player.getImage(), player.getX(), player.getY(), 80, 140,
null);
}
public b() {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
public static void slow(int n) {
long t0, t1;
t0 = System.currentTimeMillis();
do {
t1 = System.currentTimeMillis();
} while (t1 - t0 < n);
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_D) {
player.setPos(player.getX() + 6, player.getY());
}
if (e.getKeyCode() == KeyEvent.VK_A) {
player.setPos(player.getX() - 6, player.getY());
}
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
player.setPos(player.getX(), player.getY() - 60);
}
}
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
for (int i = 0; i < 20; i++) {
slow(50);
player.setPos(player.getX(), player.getY() + 2);
}
}
}
public void keyTyped(KeyEvent e) {
}
}
我的c"班(玩家):
public class c {
private ImageIcon i = new ImageIcon("guy.png");
private Image img = i.getImage();
private int x = 0;
private int y = 100;
public void wait(int what) {
try {
Thread.sleep(what);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public c() {
}
public Image getImage() {
return img;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setPos(int mx, int my) {
x = mx;
y = my;
}
}
推荐答案
我没有浏览这里的所有代码,但这里有一些提示:
I haven't gone through all the code here but here are some pointers:
- Swing 有自己的并发机制,允许您处理 UI 更新.您可以使用 Swing Timer 而不是原始
线程
.相关的是使用Thread.sleep
- 不要这样做,它只会阻止EDT
并阻止 UI 更新. - Swing 绘制链机制要求您覆盖
paintComponent
而不是paint
. - 始终使用 Key Bindings 而不是
KeyListeners
在 Swing 中.KeyListeners
需要组件焦点才能与KeyEvents
交互.Key Bindings
没有这个限制.
- Swing has its own concurrency mechanisms which allow you to handle UI updates. You can use a Swing Timer rather than a raw
Thread
. Related is the use ofThread.sleep
- don't do this, it only blocks theEDT
and prevents UI updates. - The Swing paint chain mechanism requires you to override
paintComponent
rather thanpaint
. - Always use Key Bindings rather than
KeyListeners
in Swing.KeyListeners
require component focus to work to interact with theKeyEvents
.Key Bindings
do not have this limitation.
这篇关于Java repaint() 方法并不总是有效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!