Java repaint() 方法并不总是有效 [英] Java repaint() method doesn't always work

查看:54
本文介绍了Java repaint() 方法并不总是有效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 of Thread.sleep - don't do this, it only blocks the EDT and prevents UI updates.
  • The Swing paint chain mechanism requires you to override paintComponent rather than paint.
  • Always use Key Bindings rather than KeyListeners in Swing. KeyListeners require component focus to work to interact with the KeyEvents. Key Bindings do not have this limitation.

这篇关于Java repaint() 方法并不总是有效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆