【问题标题】:How to move a circle automatically in java? [closed]如何在java中自动移动一个圆圈? [关闭]
【发布时间】:2014-05-23 09:29:49
【问题描述】:

我是 java GUI 的新手,正在努力学习它。我想自动在屏幕上移动一个圆圈(即不按任何键或执行任何其他操作)。我找到了一种通过做一些动作来移动它的方法,但这不是我需要的。请问谁能告诉我最简单的方法?

我想去掉下面代码中的动作监听器,让圆圈自动移动:

public class MyFirstGraphics extends JFrame {

    int x = 100;
    int y = 100;

    MyFirstGraphics() {
        super("Circle");
        setSize(800, 800);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setBackground(Color.pink);
        JButton f = new JButton("circle");
        f.addActionListener(new re());
        add(f, BorderLayout.NORTH);
    }

    private class re implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            for (int i = 1; i < 50; i++) {
                x++;
                y++;
                repaint();
            }
        }
    }

    public void paint(Graphics g) {
        super.paint(g);
        g.drawOval(x, y, 100, 100);
    }

    public static void main(String[] args) {
        MyFirstGraphics l = new MyFirstGraphics();
        l.setVisible(true);
    }
}

【问题讨论】:

  • 有很多关于 SO 的例子,example(滚动到底部)。您还应该查看Performing Custom Painting2D GraphicsConcurrency in SwingHow to Use Swing Timers 以了解有关如何实现的详细信息
  • 动画也不是一门简单的学科(有趣,但不简单)。上面评论中的链接示例与 Swing 一样简单
  • “我找到了一种通过执行一些操作来移动它的方法,但这不是我需要的。” 为了尽快获得更好的帮助,请发布MCVE(最低限度的完整和可验证示例)。
  • @AndrewThompson 发布了一个示例代码。
  • 对代码块使用一致且符合逻辑的缩进。代码的缩进是为了帮助人们理解程序流程。

标签: java swing animation jframe awt


【解决方案1】:

让我们从动画是随时间变化的错觉这一事实开始。此外,Swing 是单线程环境。您不能“阻止” Swing 线程(也称为事件调度线程)并让它绘制更新,您需要一些方法来定期安排更新,以便您可以应用更改然后重新绘制更改...

所以您的第一个问题在于您的 actionPerformed 方法...

for (int i = 1; i < 50; i++) {
    x++;
    y++;
    repaint();
}

基本上,唯一会被绘制的是 150x150 的球,其他任何东西都不会被绘制。

相反,您需要将其更改为类似...

public void actionPerformed(ActionEvent e) {
    if (x < 150 && y < 150) {
        x++;
        y++;
    } else {
        ((Timer)e.getSource()).stop();
    }
    repaint();
}

看看:

更多详情

一个基本的“弹力”球示例

import java.awt.BorderLayout;
import java.awt.Color;
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;

public class BounceyDot {

    public static void main(String[] args) {
        new BounceyDot();
    }

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

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

    public class TestPane extends JPanel {

        private int x = 0;
        private int y = 100;
        private int radius = 20;
        private int xDelta = 2;

        public TestPane() {
            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    x += xDelta;
                    if (x + (radius * 2) > getWidth()) {
                        x = getWidth() - (radius * 2);
                        xDelta *= -1;
                    } else if (x < 0) {
                        x = 0;
                        xDelta *= -1;
                    }
                    repaint();
                }
            });
            timer.start();
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.RED);
            g.fillOval(x, y - radius, radius * 2, radius * 2);
        }
    }

}

【讨论】:

  • 谢谢!那正是我正在寻找的东西。再次感谢。
【解决方案2】:

要为该代码设置动画,请使用基于 Swing 的 Timerre ActionListener 作为构造函数中的一个参数(另一个参数是延迟)。

有关详细信息和工作示例,请参阅 How to Use Swing Timers

【讨论】:

  • 非常感谢它真的很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-10
  • 1970-01-01
  • 1970-01-01
  • 2012-10-27
相关资源
最近更新 更多