AnimationFrame1とAnimationFrame2の2つのほぼ同じクラスがあります。これらのクラスは両方とも、500x500ウィンドウを横切って水平方向に前後に移動する青いボールを表示します。runAnimation()メソッドとcreateAndShowGUI()メソッドを除いて、2つのクラスは同じです。runAnimation()メソッドでは、AnimationFrame1はwhileループとsleepメソッドを使用してアニメーションループを作成しますが、AnimationFrame2はSwingタイマーを使用します。そのcreateAndShowGUI()メソッドで、AnimationFrame1は新しいスレッドを作成し、その上でrunAnimation()メソッドを呼び出しますが、AnimationFrame2は新しいスレッドなしで単にrunAnimation()メソッドを呼び出します。
両方のクラスをコンパイルした後、Swing Timerを使用するAnimationFrame2は、whileループとsleepメソッドを使用するAnimationFrame1で表示されるアニメーションほど途切れることのない、はるかにスムーズなアニメーションを表示することがわかりました。私の質問は、AnimationFrame1がAnimationFrame2よりもアニメーションでより多くのスタッターを表示するのはなぜですか?この理由を探しましたが、今のところ何も見つかりませんでした。
また、私は明らかにJavaの初心者なので、コードに問題がある場合、またはコードを改善できる方法を知っている場合は、お知らせください。
これがAnimationFrame1です。
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
class AnimationFrame1 extends JPanel {
int ovalX;
int prevX;
Timer timer;
boolean moveRight;
BufferedImage img;
public AnimationFrame1() {
setPreferredSize(new Dimension(500, 500));
}
public void runAnimation() {
moveRight = true;
img = null;
ovalX = 0;
prevX = 0;
while(true) {
if (moveRight == true) {
prevX = ovalX;
ovalX = ovalX + 4;
}
else {
prevX = ovalX - 4;
ovalX = ovalX - 4;
}
repaint();
if (ovalX > 430) {
moveRight = false;
}
if (ovalX == 0) {
moveRight = true;
}
try {
Thread.sleep(25);
}
catch(Exception e) {
}
}
}
public void paintComponent(Graphics g) {
if (img == null) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = getGraphicsConfiguration();
img = gc.createCompatibleImage(78, 70);
Graphics gImg = img.getGraphics();
gImg.setColor(getBackground());
gImg.fillRect(0, 0, getWidth(), getHeight());
gImg.setColor(Color.BLUE);
gImg.fillOval(4, 0, 70, 70);
gImg.dispose();
}
g.drawImage(img, ovalX, 250, null);
}
public static void createAndShowGUI() {
JFrame mainFrame = new JFrame();
final AnimationFrame1 animFrame = new AnimationFrame1();
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.add(animFrame);
mainFrame.pack();
mainFrame.createBufferStrategy(2);
mainFrame.setVisible(true);
new Thread(new Runnable() {
public void run() {
animFrame.runAnimation();
}
}).start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
そしてここにAnimationFrame2があります:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
class AnimationFrame2 extends JPanel {
int ovalX;
int prevX;
Timer timer;
boolean moveRight;
BufferedImage img;
public AnimationFrame2() {
setPreferredSize(new Dimension(500, 500));
}
public void runAnimation() {
moveRight = true;
img = null;
ovalX = 0;
prevX = 0;
timer = new Timer(25, new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (moveRight == true) {
prevX = ovalX;
ovalX = ovalX + 4;
}
else {
prevX = ovalX - 4;
ovalX = ovalX - 4;
}
repaint();
if (ovalX > 430) {
moveRight = false;
}
if (ovalX == 0) {
moveRight = true;
}
}
});
timer.start();
}
public void paintComponent(Graphics g) {
if (img == null) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = getGraphicsConfiguration();
img = gc.createCompatibleImage(78, 70);
Graphics gImg = img.getGraphics();
gImg.setColor(getBackground());
gImg.fillRect(0, 0, getWidth(), getHeight());
gImg.setColor(Color.BLUE);
gImg.fillOval(4, 0, 70, 70);
gImg.dispose();
}
g.drawImage(img, ovalX, 250, null);
}
public static void createAndShowGUI() {
JFrame mainFrame = new JFrame();
final AnimationFrame2 animFrame = new AnimationFrame2();
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.add(animFrame);
mainFrame.pack();
mainFrame.createBufferStrategy(2);
mainFrame.setVisible(true);
animFrame.runAnimation();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}