gpt4 book ai didi

java - .fillOval 坐标在 repaint() 期间未更新

转载 作者:行者123 更新时间:2023-12-02 02:02:10 25 4
gpt4 key购买 nike

我正在阅读一本(过时的)Java 书,这个项目应该“动画”一个在屏幕上移动的圆圈。然而,当程序运行时,圆圈仍停留在一处。我的代码看起来与书上的相同。我是不是忘记了什么?我是否在错误的时间调用了 repaint() ?

public class Animation 
{
JFrame f;
int x, y;
public static void main(String [] args)
{
Animation a = new Animation();
a.go();
}

public void go()
{
f=new JFrame();
myPanel p=new myPanel();

f.getContentPane().add(p);
f.setSize(300, 300);
f.setVisible(true);
for(int i=0; i<=50; i++)
{
p.repaint();
x++;
y++;
}

}

class myPanel extends JPanel
{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.GREEN);
g.fillOval(x, y, 40, 40);
}
}
}

最佳答案

所以,我立即想到了两件事。

  1. 更新值的循环可能没有在事件调度线程上运行,这可能会导致脏读/写
  2. repaint 可以合并请求以减少事件队列/事件调度线程上的工作量。由于循环中没有“人为”延迟,因此您的所有请求可能会被 RepaintManager 简化为单个更新传递

我要做的第一件事是隔离椭圆位置管理的责任,因为在您当前的代码中,它可以从任何地方更新,这简直是一团糟

class MyPanel extends JPanel {

private Point posy = new Point(0, 0);

public Point getPosy() {
return posy;
}

public void move() {
Point posy = getPosy();
posy.x++;
posy.y++;
repaint();
}

public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.GREEN);
g.fillOval(posy.x, posy.y, 40, 40);
}
}

接下来,我将确保在 EDT 内修改 UI 上下文...

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
Animation a = new Animation();
a.go();
}
});
}

最后,我将利用 Swing Timer 充当动画的伪循环...

public void go() {
f = new JFrame();
MyPanel p = new MyPanel();

f.getContentPane().add(p);
f.setSize(300, 300);
f.setVisible(true);

Timer timer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
p.move();
}
});
timer.start();

}

在此上下文中使用 Swing Timer 的原因有很多。首先,“刻度”在 EDT 上执行,从而可以安全地从内部更新 UI,并且在刻度之间“等待”时不会阻塞 UI

我建议您看一下:

关于java - .fillOval 坐标在 repaint() 期间未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51411534/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com