当前位置: 首页 > 知识库问答 >
问题:

Java图形绘制不正确

薛浩言
2023-03-14

我已经编写了以下代码

   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代码http://codepen.io/anon/pen/ZYQoQZ

任何有助于理解原因的帮助都是非常感谢的

共有2个答案

秦俊豪
2023-03-14

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

>

  • Swing GUI对象应该仅在事件分派线程上构造和操作。

    当您真正想覆盖getPreferredSize()时,不要使用setSize()

    调用pack(),让容器采用其首选大小。

    使用javax.swing.Timer来调整动画的速度。

    修订代码,合并@Mad的修复并使用drawOval()

    import java.awt.BorderLayout;
    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;
    
    final public class Test {
    
        JFrame frame;
        DrawPanel drawPanel;
        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() {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    frame = new JFrame("Test");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    drawPanel = new DrawPanel();
                    frame.add(BorderLayout.CENTER, drawPanel);
                    frame.setResizable(false);
                    frame.pack();
                    frame.setLocationByPlatform(true);
                    frame.setVisible(true);
                    Timer t = new Timer(10, new ActionListener() {
    
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            drawPanel.repaint();
                        }
                    });
                    t.start();
                }
            });
        }
    
        private class DrawPanel extends JPanel {
    
            public double getY(int i, int t) {
                return 200 + 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.drawOval(100 + 20 * k, (int) getY(k, timeStep), 8, 8);
                }
                timeStep++;
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(700, 500);
            }
    
        }
    }
    

  • 郑狐若
    2023-03-14

    有(可能)两个基本问题...

    1. getY中,您忽略了参数t,而是使用timeStep,而从技术上讲,这可能不会产生巨大的差异,这是一个值得关注的领域
    2. 您有一个整数除法问题。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。油漆组件。。。

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

    • 进行定制绘画
    • AWT和Swing绘画
    • Swing中的并发
    • 如何使用摆动计时器
    • 初始线程
     类似资料:
    • 各位程序员好, 我在代码中遇到了一个似乎无法破解的小问题。它与Java的Jframe;图形区域有关。我将在下面发布的代码是在一个绘图方法上。其目的是绘制ArrayList中的房间,该房间位于另一个类中,因此之前。这种偏离航线的情况不会发生,因此在这里发帖。 获取有关该项目的背景信息是ArrayList,其中包含各种不同大小和颜色的房间。房间本身就是物体。 首先是课程: 下面是用于创建房间的类。 我

    • 问题内容: 关闭。 此问题不符合堆栈溢出准则。它当前不接受答案。 想改善这个问题吗? 更新问题,使其成为Stack Overflow 的主题。 6年前关闭。 改善这个问题 我想用Java绘制图形(节点和边)。但是,由于我不知道该怎么做,因此在开始之前我想寻求一些建议。 我应该怎么做? 使用Graphics2D包,对吗? 节点的标签怎么样?我应该使用诸如drawString之类的东西并手动处理所有“

    • 我有一个名为pct的数据集 我想使用ggplot2或绘图包获得正条形图和负条形图。 给定下表中的数据集 我想得到这样的东西

    • 问题内容: 我正在尝试使Java 2D图形“ hello world”运行起来,并发现它异常困难(即,我正在搜索“ java hello world example”的变体,然后变成空白)。有人能帮我举一个最小的世界范例吗? 编辑 不过,这是一个不错的起点,“ Java教程:执行自定义绘画” 。 问题答案: 要在Swing中绘制矩形,您应该: 首先,永远不要直接在JFrame或其他顶级窗口中绘制。

    • 问题内容: 以前没有做过,所以显然我很烂。在此处,当前鼠标位置周围的64个像素会在窗体上绘制得更大一些。问题是,它有点“慢”,而且我不知道从哪里开始修复。 除此之外,我还创建了一个线程,该线程在完成时会不断调用更新图形,并像文本一样以每秒fps的速度调用,以真正显示绘制速度。 替代文字 代码示例: 所做的更改: 添加了“ gc.dispose();” 添加了“ isdone”,因此不能更快地调用重

    • 问题内容: 我正在尝试将一些简单的图形绘制到框架上。我还希望能够从主要方法中调整要绘制的内容。例如,设置要打印的String变量或矩形的坐标。 我似乎遇到的问题是,可以在设置类变量之前调用该方法。如何在绘制到屏幕之前更改此代码以设置/ 变量? 谢谢 问题答案: 从FrameTest类中删除test_string。使用set方法直接设置test_string。参见示例: