2 xkz 5413 xkz_5413 于 2014.12.03 23:18 提问

java里repaint在循环里的问题

package test05;

//import java.awt.Color;
//import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.*;
import javax.swing.*;
//import javax.swing.JFrame;
//import javax.swing.JPanel;

public class Show extends JFrame {
MyPanel mp = null;

public Show() {
    mp = new MyPanel();
    this.add(mp);
    this.addKeyListener(mp);
    //
    this.setSize(900, 600);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setVisible(true);
}

public static void main(String[] args) {
    Show show = new Show();

}

}

class MyPanel extends JPanel implements KeyListener {

int x = 200;
int y = 200;

public MyPanel() {

}

public void paint(Graphics g) {
    super.paint(g);
    g.setColor(Color.BLACK);
    g.fillOval(200, 200, 10, 10);
    g.setColor(Color.red);
    g.fillOval(x, y, 5, 5);
    System.out.println("aaa");
}

@Override
public void keyTyped(KeyEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void keyPressed(KeyEvent e) {
    System.out.println(this.x);
    if (e.getKeyCode() == KeyEvent.VK_J) {

        while (!(x >= 900 || x <= 0 || y >= 600 || y <= 0)) {
            this.repaint();
            System.out.println("b");
            this.x -= 5;
            System.out.println(x);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            this.repaint();
        }
        System.out.println("cccccc");

    }

}

@Override
public void keyReleased(KeyEvent e) {
    // TODO Auto-generated method stub

}

}

就是这个循环的问题
if (e.getKeyCode() == KeyEvent.VK_J) {
while (!(x >= 900 || x <= 0 || y >= 600 || y <= 0)) {
this.repaint();
this.x -= 5;
this.repaint();
}
}

repaint在出while循环后才执行,怎么回事

1个回答

eagleyan
eagleyan   Rxr 2014.12.04 00:23

根据javadoc, “If this component is a lightweight component, this method causes a call to this component's paint method as soon as possible. Otherwise, this method causes a call to this component's update method as soon as possible.” repaint不能保证调用立刻刷新。JPanel实际上是调用update,merge你的请求之后进行刷新。如果你的确要求立刻刷新,你可以调用paintImmediately

eagleyan
eagleyan 回复xkz_5413: 你要是没有疑问了,就采纳我的答案吧
大约 3 年之前 回复
eagleyan
eagleyan http://www.javamex.com/tutorials/threads/swing_ui.shtml
大约 3 年之前 回复
eagleyan
eagleyan 回复xkz_5413: 在事件处理程序里放置复杂逻辑一半不是很好的事情,尤其是sleep,这样导致你的事件被阻塞,编程当中应该避免.这里有例子
大约 3 年之前 回复
xkz_5413
xkz_5413 恩,谢谢。这个是学多线程的时候,用多线程实现的,我就想看看循环的效果是什么样的。
大约 3 年之前 回复
eagleyan
eagleyan 回复xkz_5413: 不是说都是一起刷新,java内部有一个queue来处理你的keypressed,而当你调用repaint的时候,又加了一事件到queue里面。你有个办法可以达到你的目的,就是利用另外一个线程去做这件事。new Thread() { public void run() { while (!(x >= 900 || x <= 0 || y >= 600 || y <= 0)) { this.repaint(); this.x -= 5; final MyPanel mp = this; Thread.sleep(100); SwingUtilities.invokeLater(new Runnable() { mp.repaint(); } } } }
大约 3 年之前 回复
xkz_5413
xkz_5413 还有要起到重绘的作用还得repaint,paintImmediately不适用,有没有在循环里调repaint的时候repaint立刻刷新的方法呢?
大约 3 年之前 回复
xkz_5413
xkz_5413 那我这样写,每次while循环都会有一个repaint调用,这些所有的repaint都是最后一起刷新的吗?
大约 3 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!