Java repaint()方法并不总是有效

Boo*_*gly -1 java swing repaint

Java中的repaint()方法存在问题.我创建了一个不断重新绘制屏幕的新线程.当我释放空格键时,我希望我的播放器通过设置其位置然后等待50毫秒并循环20次来顺利下降.相反,它在循环中等待整个时间,然后重新绘制.我想知道为什么它不会不断重现球员坐标的变化.谢谢.

(编辑)感谢大家的帮助.这是我第一次使用堆栈溢出,而我只有13,仍在学习java,所以我可能会再次回到教程.

我的'一级'(主要):

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的'b'级(JPanel /绘图):

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) {
    }
}
Run Code Online (Sandbox Code Playgroud)

我的'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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Rei*_*eus 5

我没有完成所有代码,但这里有一些指示:

  • Swing有自己的并发机制,允许您处理UI更新.您可以使用Swing Timer而不是raw Thread.相关的是使用Thread.sleep- 不要这样做,它只阻止EDT和阻止UI更新.
  • Swing油漆链机制要求您覆盖paintComponent而不是paint.
  • 始终使用键绑定而不是KeyListenersSwing.KeyListeners需要组件焦点才能与之交互KeyEvents.Key Bindings没有这个限制.