如何在java中自动移动圆圈?

时间:2014-05-23 00:25:36

标签: java swing animation jframe awt

我是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);
    }
}

2 个答案:

答案 0 :(得分:5)

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

所以你的第一个问题出在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();
}

看看:

了解更多详情

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

Bounce

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);
        }
    }

}

答案 1 :(得分:2)

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

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