Java图形绘制不正确

Java图形绘制不正确,java,swing,Java,Swing,我已经编写了以下代码 import java.awt.BorderLayout; import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; final public class Test { JFrame frame; DrawPanel drawPanel; boolean up = false; boolean down = true; b

我已经编写了以下代码

   import java.awt.BorderLayout;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

final public class Test
{

    JFrame frame;
    DrawPanel drawPanel;
    boolean up = false;
    boolean down = true;
    boolean left = false;
    boolean right = true;
    private int timeStep = 0;
    private int ballYTravel = 100;
    private int BALL_NUM = 24;

    public static void main(String... args)
    {
        new Test().go();
    }

    private void go()
    {
        frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        drawPanel = new DrawPanel();

        frame.getContentPane().add(BorderLayout.CENTER, drawPanel);

        frame.setResizable(false);
        frame.setSize(800, 600);
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
        moveIt();
    }

    class DrawPanel extends JPanel
    {
        private static final long serialVersionUID = 1L;
        public double getY(int i, int t) {
            return 200 + ballYTravel / 2 * (Math.sin(timeStep * (i / 200 + 0.08)));
        }

        public void paintComponent(Graphics g)
        {    
            for (int k = 0; k < BALL_NUM; k++ ) {
                g.fillRect(100  + 20 *k , (int) getY(k, timeStep), 6, 6);
            }
            timeStep++;

        }
    }



    private void moveIt()
    {
        while (true)
        {

            try
            {
                Thread.sleep(10);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            frame.repaint();
        }
    }
    }
它运行并设置动画,但是它的设置动画的方式与我引用的Javascript代码不同,可以在这里找到Javascript代码


如果有人帮助你理解为什么会受到赞赏

你的音译会暴露出几个问题:

Swing GUI对象应仅在上构造和操作

当您真的想覆盖时,不要使用setSize

调用pack以使容器采用其首选大小

用于调整动画的速度

修订代码,包括@Mad并使用drawOval:


你的音译揭示了几个问题:

Swing GUI对象应仅在上构造和操作

当您真的想覆盖时,不要使用setSize

调用pack以使容器采用其首选大小

用于调整动画的速度

修订代码,包括@Mad并使用drawOval:


可能有两个基本问题

在getY中,您忽略了参数t,而是使用timeStep,虽然从技术上讲,这可能不会产生巨大的差异,但这是一个值得关注的领域 您有整数除法问题。i/200将产生int结果,在这里您确实需要一个双精度。将其更改为i/200d 例如

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

final public class Test {

    private int timeStep = 0;
    private final int ballYTravel = 100;
    private final int BALL_NUM = 24;

    public static void main(String... args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new DrawPanel());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    class DrawPanel extends JPanel {

        private static final long serialVersionUID = 1L;

        public DrawPanel() {
            new Timer(10, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    timeStep++;
                    repaint();
                }
            }).start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 200);
        }

        public double getY(int i, int t) {
            return 100 + ballYTravel / 2 * (Math.sin(t * (i / 200d + 0.08)));
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            for (int k = 0; k < BALL_NUM; k++) {
                g.fillRect(10 + 20 * k, (int) getY(k, timeStep), 6, 6);
            }

        }
    }
}
您还破坏了油漆链,这将导致您长期出现问题,请确保您正在调用super.paintComponent

有关更多详细信息,请参阅


可能有两个基本问题

在getY中,您忽略了参数t,而是使用timeStep,虽然从技术上讲,这可能不会产生巨大的差异,但这是一个值得关注的领域 您有整数除法问题。i/200将产生int结果,在这里您确实需要一个双精度。将其更改为i/200d 例如

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

final public class Test {

    private int timeStep = 0;
    private final int ballYTravel = 100;
    private final int BALL_NUM = 24;

    public static void main(String... args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new DrawPanel());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    class DrawPanel extends JPanel {

        private static final long serialVersionUID = 1L;

        public DrawPanel() {
            new Timer(10, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    timeStep++;
                    repaint();
                }
            }).start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 200);
        }

        public double getY(int i, int t) {
            return 100 + ballYTravel / 2 * (Math.sin(t * (i / 200d + 0.08)));
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            for (int k = 0; k < BALL_NUM; k++) {
                g.fillRect(10 + 20 * k, (int) getY(k, timeStep), 6, 6);
            }

        }
    }
}
您还破坏了油漆链,这将导致您长期出现问题,请确保您正在调用super.paintComponent

有关更多详细信息,请参阅


…但是,它不是以相同的方式进行动画制作…-你能更具描述性一点吗?注意-你应该使用一个摆动计时器来驱动你的动画,而不是使用Thread.sleep的while true循环。这样会导致线程灾难。该链接可以在选项卡中找到。您需要将所有动画代码从paintComponent中取出并放入您的。paintComponent方法应该只绘制一次球,就这样,没有for循环,除非同时绘制多个球。另请参阅。在这篇文章中,我们将研究一个工作示例和几个变体…但是它不是以相同的方式制作动画…-你能更具描述性一点吗?注意-你应该使用一个摆动计时器来驱动你的动画,而不是使用Thread.sleep的while true循环。这样会导致线程灾难。该链接可以在选项卡中找到。您需要将所有动画代码从paintComponent中取出并放入您的。paintComponent方法应该只绘制一次球,就这样,没有for循环,除非同时绘制多个球。另请参阅。本文将研究一个工作示例和几个变体。