简体   繁体   English

Java中的while循环未调用Repaint()

[英]Repaint() is not being called in Java while loop

I'm attempting to create a simple animation in Java that displays a blue ball moving horizontally part way across a 500 x 500 window. 我正在尝试用Java创建一个简单的动画,该动画显示一个蓝色的球在500 x 500的窗口中水平移动。 The ball is supposed to move at a rate of 1px/30ms. 该球应该以1px / 30ms的速度移动。 The problem is, is that the window is only being painted when the while loop exits and not during every iteration of the while loop as I intended. 问题是,仅在while循环退出时才绘制窗口,而不是在while循环的每次迭代中绘制窗口。 This results in the blue ball being painted in its final location. 这导致蓝色球在其最终位置被绘制。 Could you please tell me what I'm doing wrong here? 您能告诉我我在做什么错吗? I've also tried executing this code on the EDT with the paintComponent() method and got the same result. 我也尝试使用paintComponent()方法在EDT上执行此代码,并得到相同的结果。 In addition, as suggested by other posts, I got the same result when using paintImmediately(0, 0, getWidth(), getHeight()) instead of repaint() while using the EDT and paintComponent() method. 此外,正如其他文章所建议的那样,当使用EDT和paintComponent()方法使用paintImmediately(0,0,getWidth(),getHeight())而不是repaint()时,我得到了相同的结果。 I'm trying to do all of this without using timers. 我正在尝试不使用计时器来完成所有这些操作。

import javax.swing.*;
import java.awt.*;

class AnimationFrame extends JPanel {

    int ovalX = 50;
    long animDuration = 5000;
    long currentTime = System.nanoTime() / 1000000;
    long startTime = currentTime;
    long elapsedTime = currentTime - startTime;

    public AnimationFrame() {
        setPreferredSize(new Dimension(500, 500));
        runAnimation();
    }

    public void runAnimation() {
        while (elapsedTime < animDuration) {
            currentTime = System.nanoTime() / 1000000;
            elapsedTime = currentTime - startTime;
            System.out.println(elapsedTime);
            ovalX = ovalX + 1;
            try {
                Thread.sleep(30);
            }
            catch (Exception e) {
            }
            repaint();
        }
    }

    public void paint(Graphics g) {
        Rectangle clip = g.getClipBounds();
        g.setColor(Color.BLACK);
        g.fillRect(clip.x, clip.y, clip.width, clip.height);
        g.setColor(Color.BLUE);
        g.fillOval(ovalX, 250, 70, 70);
    }

    public static void main(String[] args) {
        createAndShowGUI();
    }

    public static void createAndShowGUI() {
        JFrame mainFrame = new JFrame();
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.add(new AnimationFrame());
        mainFrame.pack();
        mainFrame.setVisible(true);
    }
}

I looked at your code and noticed that you are calling the method that runs the animation from within the constructor of the "AnimationFrame" which you are adding to your "mainFrame". 我查看了您的代码,发现您正在从要添加到“ mainFrame”的“ AnimationFrame”的构造函数中调用运行动画的方法。

The problems with doing it that way is that you are trying to animate before the object has finished being constructed, which must be completed before it can be added to the mainFrame, which is not yet made to be visible on the screen. 这样做的问题在于,您试图在对象完成构造之前进行动画处理,必须先完成动画处理才能将其添加到尚未在屏幕上可见的mainFrame中。

I made the follow changes to your code and I see a blue ball move across the frame now. 我对您的代码进行了以下更改,现在我看到一个蓝色的球在框架上移动。

import javax.swing.*;
import java.awt.*;

class AnimationFrame extends JPanel {

    int ovalX = 50;
    long animDuration = 5000;
    long currentTime = System.nanoTime() / 1000000;
    long startTime = currentTime;
    long elapsedTime = currentTime - startTime;

    public AnimationFrame() {
        setPreferredSize(new Dimension(500, 500));
        //i removed the call to runAnimation from here

    }

    public void runAnimation() {
        while (elapsedTime < animDuration) {
            currentTime = System.nanoTime() / 1000000;
            elapsedTime = currentTime - startTime;
            System.out.println(elapsedTime);
            ovalX = ovalX + 1;
            try {
                Thread.sleep(30);
            }
            catch (Exception e) {
            }
            repaint();
        }
    }

    @Override
    public void paint(Graphics g) {
        Rectangle clip = g.getClipBounds();
        g.setColor(Color.BLACK);
        g.fillRect(clip.x, clip.y, clip.width, clip.height);
        g.setColor(Color.BLUE);
        g.fillOval(ovalX, 250, 70, 70);
    }

    public static void main(String[] args) {
        createAndShowGUI();
    }

    public static void createAndShowGUI() {
        JFrame mainFrame = new JFrame();
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        AnimationFrame animationPanel = new AnimationFrame();
        mainFrame.add(animationPanel);
        mainFrame.pack();
        mainFrame.setVisible(true);
        //I made the call to runAnimation here now
        //after the containing frame is visible.
        animationPanel.runAnimation();
    }
}

You need to do the loop in a separate thread. 您需要在单独的线程中执行循环。 See this tutorial- http://101.lv/learn/Java/ch10.htm 参见本教程-http://101.lv/learn/Java/ch10.htm

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM