Java 定时器动作监听器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22366890/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java timer action listener
提问by user3363135
could use your help homework involving swing timers, action listeners and multiple objects. I don't know if posting the question is allowed here but i'm having trouble with the animation, here's what i have so far
可以使用您的帮助作业,涉及摆动计时器、动作侦听器和多个对象。我不知道这里是否允许发布问题,但我在动画方面遇到了问题,这是我目前所拥有的
Create a class Particle that has two double fields x and y, a constructor that initializes these fields to random values between 0 and 500, methods getX and getY that return their values, and a method void move() that randomly adds or subtracts one to each of the values of x and y. (The quantities added to x and y are two separate random numbers.) Next, create a class ParticleFieldWithTimer that extends JPanel. This class should prefer to be 500 * 500 pixels in size. Its constructor should first fill an ArrayList field with 100 Particle objects, then start a Swing Timer that ticks 25 times a second. At each tick, the action listener should first call the method move for each particle, and then call repaint. The paintComponent method of ParticleFieldWithTimer should draw each particle as a 3*3 rectangle to its current coordinates. Make sure that the Timer will stop when the user closes the frame
创建一个具有两个双字段 x 和 y 的类 Particle,一个将这些字段初始化为 0 到 500 之间的随机值的构造函数,返回它们值的方法 getX 和 getY,以及一个随机添加或减去一个的方法 void move() x 和 y 的每个值。(添加到 x 和 y 的数量是两个单独的随机数。)接下来,创建一个扩展 JPanel 的类 ParticleFieldWithTimer。这个类的大小应该是 500 * 500 像素。它的构造函数应该首先用 100 个 Particle 对象填充一个 ArrayList 字段,然后启动一个每秒滴答 25 次的 Swing Timer。在每个滴答声中,动作监听器应该首先为每个粒子调用 move 方法,然后调用 repaint。ParticleFieldWithTimer 的paintComponent 方法应该将每个粒子绘制为其当前坐标的3*3 矩形。确保当用户关闭框架时计时器将停止
This is the ParticleFieldWithTimer class
这是 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);
}
}
This is the particle class
这是粒子类
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);
}
}
}
采纳答案by MadProgrammer
This...
这个...
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();
}
});
}
Is the wrong approach, it is create a 100 Timer
s, which will affect the performance of your system.
是错误的做法,它是创建一个 100 Timer
s,这会影响您系统的性能。
You are also creating a new Particle
each time the timer ticks, which isn't what you really want to do either, you want to affect the Particle
s you've already created...
Particle
每次计时器滴答作响时,您也在创建一个新的,这也不是您真正想要做的,您想影响Particle
您已经创建的s...
Instead, create your particles...
相反,创建您的粒子...
for(int i = 0; i < 100; i++) {
particle.add(new Particle());
}
Then create your Timer
and within it, iterate through the particles you've already created...
然后创建您的Timer
并在其中迭代您已经创建的粒子......
timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
for (Particle p : particle) {
p.move();
}
repaint();
}
});
Don't forget to start the timer...
别忘了启动计时器...
timer.start();
Or change the color of the Graphics
context, which is probably still set to the background of the panel...
或者更改Graphics
上下文的颜色,它可能仍然设置为面板的背景......
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.RED);
for (Particle p : particle) {
I also noted that...
我还注意到...
x = r.nextInt(2) - 1;
y = r.nextInt(2) - 1;
Isn't doing what you want. It will always make the values between -1 and 1. Instead, you want to add the result to the x/y values...
不是在做你想做的。它将始终使值介于 -1 和 1 之间。相反,您希望将结果添加到 x/y 值...
x += r.nextInt(2) - 1;
y += r.nextInt(2) - 1;
Now, this kind of made the values "drag" across the screen in a (mostly) uniform manner...
现在,这种方式使值以(大部分)统一的方式在屏幕上“拖动”......
You could try using...
你可以尝试使用...
x += r.nextBoolean() ? 1 : - 1;
y += r.nextBoolean() ? 1 : - 1;
But this ended up making them dance around in place (mostly)...
但这最终让他们在原地跳舞(主要是)......