1

500x500ウィンドウの途中で水平方向に移動する青いボールを表示する単純なアニメーションをJavaで作成しようとしています。ボールは1px/30msの速度で動くことになっています。問題は、ウィンドウが描画されるのはwhileループが終了したときだけであり、意図したようにwhileループが繰り返されるたびではないということです。これにより、青いボールが最終的な位置にペイントされます。ここで私が間違っていることを教えてください。また、paintComponent()メソッドを使用してEDTでこのコードを実行しようとしましたが、同じ結果が得られました。さらに、他の投稿で示唆されているように、EDTおよびpaintComponent()メソッドを使用しているときにrepaint()の代わりにpaintImmediately(0、0、getWidth()、getHeight())を使用すると、同じ結果が得られました。私はタイマーを使わずにこれらすべてをやろうとしています。

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);
    }
}
4

2 に答える 2

4

コードを調べたところ、「mainFrame」に追加している「AnimationFrame」のコンストラクター内からアニメーションを実行するメソッドを呼び出していることがわかりました。

この方法の問題は、オブジェクトの構築が完了する前にアニメーション化しようとしていることです。これは、まだ画面に表示されていないメインフレームに追加する前に完了する必要があります。

コードに次の変更を加えたところ、青いボールがフレームを横切って移動しているのがわかります。

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();
    }
}
于 2013-01-15T18:53:47.650 に答える
1

別のスレッドでループを実行する必要があります。このチュートリアルを参照してください-http://101.lv/learn/Java/ch10.htm

于 2013-01-15T18:36:26.523 に答える