Java计时器动作监听器

时间:2014-03-13 00:42:20

标签: java swing timer paintcomponent

可以使用你的帮助作业,包括挥杆计时器,动作听众和多个物体。我不知道是否允许在这里发布问题,但我遇到了动画问题,这是我到目前为止所拥有的

  

创建一个具有两个双字段x和y的粒子,a   构造函数,将这些字段初始化为0之间的随机值   500,返回值的方法getX和getY,以及方法   void move()随机地为每个值添加或减去一个   x和y。 (添加到x和y的数量是两个单独的随机数   数字。)接下来,创建一个扩展的类ParticleFieldWithTimer   JPanel的。此类应该更喜欢500 * 500像素的大小。它的   构造函数应首先使用100填充ArrayList字段   粒子对象,然后启动一个滴答25次的Swing Timer   第二。在每个tick,动作监听器应首先调用该方法   移动每个粒子,然后调用重绘。 paintComponent   ParticleFieldWithTimer的方法应该将每个粒子绘制为3 * 3   矩形到它的当前坐标。确保定时器将   当用户关闭框架时停止

这是ParticleFieldWithTimer类

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;


public class ParticleFieldWithTimer extends JPanel{
    private ArrayList<Particle> particle = new ArrayList<Particle>();
    Timer timer; 
    boolean b; 
    public ParticleFieldWithTimer (){
        this.setPreferredSize(new Dimension(500,500));


    for(int i = 0; i < 100; i++) { 
        particle.add(new Particle());
        timer = new Timer(40, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                // change polygon data
                // ...
                Particle p = new Particle();
                p.move();
                repaint();

            }
        });


    }





}
   public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        for (Particle p: particle) {

        double temp1 = p.getX();
        double temp2 = p.getX();
        int tempX = (int) temp1;
        int tempY = (int) temp2;
        g2.fillRect(tempX, tempY, 3, 3);
        }




    }
   public static void main(String[] args) {
        final JFrame f = new JFrame("ParticleField");
        final ParticleFieldWithTimer bb = new ParticleFieldWithTimer();
        f.setLayout(new FlowLayout());
        f.add(bb);
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we) {
                try {
                    bb.finalize();
                } catch (Throwable e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                f.dispose();
            }
        });
        f.pack();
        f.setVisible(true);
    }
}

这是粒子类

import java.util.Random;


public class Particle {
private double x , y ;

Random r = new Random();
public Particle () {

    x = r.nextDouble()*500;
    y = r.nextDouble()*500;

}
public Double getX() {
    return x;
}
public Double getY() {
    return y;
}
public void move() {

    x = r.nextInt(2) - 1;
    y = r.nextInt(2) - 1;
    System.out.println(x + "  " + y);
}

}

1 个答案:

答案 0 :(得分:4)

此...

for(int i = 0; i < 100; i++) { 
    particle.add(new Particle());
    timer = new Timer(40, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            // change polygon data
            // ...
            Particle p = new Particle();
            p.move();
            repaint();

        }
    });
}

是错误的方法,它会创建一个100 Timer s,这会影响系统的性能。

每次计时器滴答时你也会创建一个新的Particle,这不是你真正想做的,你想要影响你已经创建的Particle

相反,创建你的粒子......

for(int i = 0; i < 100; i++) { 
    particle.add(new Particle());
}

然后创建你的Timer并在其中迭代你已经创建的粒子......

timer = new Timer(40, new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent ae) {
        for (Particle p : particle) {
            p.move();
        }
        repaint();
    }
});

别忘了启动计时器...

timer.start();

或者更改Graphics上下文的颜色,该上下文可能仍然设置为面板的背景...

Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.RED);
for (Particle p : particle) {

我也注意到......

x = r.nextInt(2) - 1;
y = r.nextInt(2) - 1;

没有做你想做的事。它将始终使值介于-1和1.而是要将结果添加到x / y值...

x += r.nextInt(2) - 1;
y += r.nextInt(2) - 1;

现在,这种价值使得价值以(大部分)统一的方式在屏幕上“拖动”......

您可以尝试使用...

x += r.nextBoolean() ? 1 : - 1;
y += r.nextBoolean() ? 1 : - 1;

但最终让他们在原地跳舞(大多数)......