Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 图形对象不会随着xPosition的更新而更新_Java_Render_Increment - Fatal编程技术网

Java 图形对象不会随着xPosition的更新而更新

Java 图形对象不会随着xPosition的更新而更新,java,render,increment,Java,Render,Increment,我试图创建一个行星(蓝色圆圈),并在更新x位置时使其移动。这是主要课程 import java.awt.Canvas; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JFrame; public class Main extends Canvas implements Runnable{

我试图创建一个行星(蓝色圆圈),并在更新x位置时使其移动。这是主要课程

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JFrame;

public class Main extends Canvas implements Runnable{

    public int width = 1400;
    public int height = (width/16)* 9;

    Dimension dim = new Dimension(width, height);

    JFrame frame;

    boolean running;

    NewBody earth;

    public Main(){
        this.setPreferredSize(dim);
        this.setBackground(Color.BLACK);
    }

    public void start(){
        running = true;

        Thread thread = new Thread(this, "display");
        thread.start();
    }

    public void run(){
        long startTime = System.currentTimeMillis();
        double conv = Math.pow(10, 3);

        while(running){     
            long now = System.currentTimeMillis();
            if((now-startTime)/conv >= 1){
                earth.incXPos();
                startTime = now;
                return;
            }   

            update();
        }
    }

    public void update(){
        repaint();

    }

    public void stop(){
        running = false;
    }

    public void paint(Graphics g){
        Graphics2D g2d = (Graphics2D)g;
        g2d.setColor(Color.BLUE);
        g2d.fillOval(earth.xPos,earth.yPos, earth.radius*2, earth.radius*2);

    }

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

        main.frame = new JFrame();
        main.frame.setResizable(false);
        main.frame.add(main);
        main.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        main.frame.pack();

        main.frame.setVisible(true);

        main.earth = new NewBody(0, 0,0, 50);

        main.start();
    }
}
这是我创造“地球”的新人蓝图

问题是,当我运行程序时,蓝色圆圈只是停留在相同的位置,在那里它被初始化。它只是闪烁的非常快,没有别的事情发生。我对编码很陌生,我似乎没有收到任何错误信息,因此我不知道如何继续。我已经在这个问题上纠缠了好几个小时了


你有什么想法吗

返回
run()
方法中的code>语句导致该方法短路退出,因此在调用
incXPos()
一次后立即退出。这甚至发生在调用
update()
之前,因此永远不会调用
repaint()

不过,我会做一些不同的事情:

  • 我会画一张JPanel
  • 我会使用它的paintComponent方法
  • 我会使用Swing计时器而不是线程来执行动画循环
  • 我一定要在我的覆盖内调用super的
    paintComponent(g)

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class SimpleAnimation extends JPanel {
   private static final int PREF_W = 1400;
   private static final int PREF_H = (PREF_W * 9) / 16; // do int mult **first**
   private static final int TIMER_DELAY = 13;
   private NewBody earth = new NewBody(0, 0, 0, 50);

   public SimpleAnimation() {
      new Timer(TIMER_DELAY, new TimerListener()).start();
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;

      // to allow for smooth graphics
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

      g2d.setColor(Color.BLUE);
      g2d.fillOval(earth.xPos, earth.yPos, earth.radius * 2, earth.radius * 2);
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         earth.incXPos();
         repaint();
      }
   }

   private static void createAndShowGui() {
      SimpleAnimation mainPanel = new SimpleAnimation();

      JFrame frame = new JFrame("SimpleAnimation");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class NewBody {

   // !! Main main = new Main();

   public int xOrigo = 1400 / 2;
   public int yOrigo = 800 / 2;

   public double mass;
   public double velocity;
   public int xPos;
   public int yPos;
   public double force;
   public double vectorAngle;
   public double fx;
   public double fy;
   public double acceleration;
   public int radius;

   public NewBody(double mass, int xPos, int yPos, int radius) {
      this.mass = mass;
      this.xPos = xOrigo + xPos - radius;
      this.yPos = yOrigo + yPos - radius;
      this.radius = radius;
   }

   public void incXPos() {
      this.xPos++;
   }
}

返回run()
方法中的code>语句导致该方法短路退出,因此在调用
incXPos()
一次后立即退出。这甚至发生在调用
update()
之前,因此永远不会调用
repaint()

不过,我会做一些不同的事情:

  • 我会画一张JPanel
  • 我会使用它的paintComponent方法
  • 我会使用Swing计时器而不是线程来执行动画循环
  • 我一定要在我的覆盖内调用super的
    paintComponent(g)

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class SimpleAnimation extends JPanel {
   private static final int PREF_W = 1400;
   private static final int PREF_H = (PREF_W * 9) / 16; // do int mult **first**
   private static final int TIMER_DELAY = 13;
   private NewBody earth = new NewBody(0, 0, 0, 50);

   public SimpleAnimation() {
      new Timer(TIMER_DELAY, new TimerListener()).start();
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;

      // to allow for smooth graphics
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

      g2d.setColor(Color.BLUE);
      g2d.fillOval(earth.xPos, earth.yPos, earth.radius * 2, earth.radius * 2);
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         earth.incXPos();
         repaint();
      }
   }

   private static void createAndShowGui() {
      SimpleAnimation mainPanel = new SimpleAnimation();

      JFrame frame = new JFrame("SimpleAnimation");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class NewBody {

   // !! Main main = new Main();

   public int xOrigo = 1400 / 2;
   public int yOrigo = 800 / 2;

   public double mass;
   public double velocity;
   public int xPos;
   public int yPos;
   public double force;
   public double vectorAngle;
   public double fx;
   public double fy;
   public double acceleration;
   public int radius;

   public NewBody(double mass, int xPos, int yPos, int radius) {
      this.mass = mass;
      this.xPos = xOrigo + xPos - radius;
      this.yPos = yOrigo + yPos - radius;
      this.radius = radius;
   }

   public void incXPos() {
      this.xPos++;
   }
}

返回run()
方法中的code>语句导致该方法短路退出,因此在调用
incXPos()
一次后立即退出。这甚至发生在调用
update()
之前,因此永远不会调用
repaint()

不过,我会做一些不同的事情:

  • 我会画一张JPanel
  • 我会使用它的paintComponent方法
  • 我会使用Swing计时器而不是线程来执行动画循环
  • 我一定要在我的覆盖内调用super的
    paintComponent(g)

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class SimpleAnimation extends JPanel {
   private static final int PREF_W = 1400;
   private static final int PREF_H = (PREF_W * 9) / 16; // do int mult **first**
   private static final int TIMER_DELAY = 13;
   private NewBody earth = new NewBody(0, 0, 0, 50);

   public SimpleAnimation() {
      new Timer(TIMER_DELAY, new TimerListener()).start();
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;

      // to allow for smooth graphics
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

      g2d.setColor(Color.BLUE);
      g2d.fillOval(earth.xPos, earth.yPos, earth.radius * 2, earth.radius * 2);
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         earth.incXPos();
         repaint();
      }
   }

   private static void createAndShowGui() {
      SimpleAnimation mainPanel = new SimpleAnimation();

      JFrame frame = new JFrame("SimpleAnimation");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class NewBody {

   // !! Main main = new Main();

   public int xOrigo = 1400 / 2;
   public int yOrigo = 800 / 2;

   public double mass;
   public double velocity;
   public int xPos;
   public int yPos;
   public double force;
   public double vectorAngle;
   public double fx;
   public double fy;
   public double acceleration;
   public int radius;

   public NewBody(double mass, int xPos, int yPos, int radius) {
      this.mass = mass;
      this.xPos = xOrigo + xPos - radius;
      this.yPos = yOrigo + yPos - radius;
      this.radius = radius;
   }

   public void incXPos() {
      this.xPos++;
   }
}

返回run()
方法中的code>语句导致该方法短路退出,因此在调用
incXPos()
一次后立即退出。这甚至发生在调用
update()
之前,因此永远不会调用
repaint()

不过,我会做一些不同的事情:

  • 我会画一张JPanel
  • 我会使用它的paintComponent方法
  • 我会使用Swing计时器而不是线程来执行动画循环
  • 我一定要在我的覆盖内调用super的
    paintComponent(g)

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class SimpleAnimation extends JPanel {
   private static final int PREF_W = 1400;
   private static final int PREF_H = (PREF_W * 9) / 16; // do int mult **first**
   private static final int TIMER_DELAY = 13;
   private NewBody earth = new NewBody(0, 0, 0, 50);

   public SimpleAnimation() {
      new Timer(TIMER_DELAY, new TimerListener()).start();
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;

      // to allow for smooth graphics
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

      g2d.setColor(Color.BLUE);
      g2d.fillOval(earth.xPos, earth.yPos, earth.radius * 2, earth.radius * 2);
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         earth.incXPos();
         repaint();
      }
   }

   private static void createAndShowGui() {
      SimpleAnimation mainPanel = new SimpleAnimation();

      JFrame frame = new JFrame("SimpleAnimation");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class NewBody {

   // !! Main main = new Main();

   public int xOrigo = 1400 / 2;
   public int yOrigo = 800 / 2;

   public double mass;
   public double velocity;
   public int xPos;
   public int yPos;
   public double force;
   public double vectorAngle;
   public double fx;
   public double fy;
   public double acceleration;
   public int radius;

   public NewBody(double mass, int xPos, int yPos, int radius) {
      this.mass = mass;
      this.xPos = xOrigo + xPos - radius;
      this.yPos = yOrigo + yPos - radius;
      this.radius = radius;
   }

   public void incXPos() {
      this.xPos++;
   }
}

谢谢你的意见。为什么会短路?是因为while循环中的“return”语句吗?好吧,那么你是建议我把画布一起移走?为什么JPanel比Canvas好?我会查看swing timer,谢谢!:)@Arcthor:它会短路,因为return会立即从方法中退出。只循环一次的while循环不是一个非常有用的构造。默认情况下,使用JPanel的paintComponent方法可以提供双缓冲图形。非常感谢。真的很有帮助。如果你不介意的话,我还有一个问题。为什么我不应该在NewBody中创建一个主构造函数?如果我不能做到这一点,我如何访问widt和height等变量?@arctor:如果你在NewBody中创建一个新的主对象,它将是一个全新的、独特的对象,一个与原始主对象完全不同的对象,这不会太有帮助。如果您需要NewBody中的主实例,您将希望传入引用,可能是在构造函数中。感谢您的输入。为什么会短路?是因为while循环中的“return”语句吗?好吧,那么你是建议我把画布一起移走?为什么JPanel比Canvas好?我会查看swing timer,谢谢!:)@Arcthor:它会短路,因为return会立即从方法中退出。只循环一次的while循环不是一个非常有用的构造。默认情况下,使用JPanel的paintComponent方法可以提供双缓冲图形。非常感谢。真的很有帮助。如果你不介意的话,我还有一个问题。为什么我不应该在NewBody中创建一个主构造函数?如果我不能做到这一点,我如何访问widt和height等变量?@arctor:如果你在NewBody中创建一个新的主对象,它将是一个全新的、独特的对象,一个与原始主对象完全不同的对象,这不会太有帮助。如果您需要NewBody中的主实例,您将希望传入引用,可能是在构造函数中。感谢您的输入。为什么会短路?是因为while循环中的“return”语句吗?好吧,那么你是建议我把画布一起移走?为什么JPanel比Canvas好?我会查看swing timer,谢谢!:)@Arcthor:它会短路,因为return会立即从方法中退出。只循环一次的while循环不是一个非常有用的构造。默认情况下,使用JPanel的paintComponent方法可以提供双缓冲图形。非常感谢。真的很有帮助。如果你不介意的话,我还有一个问题。为什么我不应该在NewBody中创建一个主构造函数?如果我不能做到这一点,我如何访问widt和height等变量?@arctor:如果你在NewBody中创建一个新的主对象,它将是一个全新的、独特的对象,一个与原始主对象完全不同的对象