[英]How to implement multiple timers in Java Swing
我為我的一組圖標設置了一個timer
,可以為這些圖標設置動畫。 基本上 - 我有一個世界 map 作為背景和汽車、飛機等。 此 map 上的圖標“浮動”。 我正在使用swing timer
來執行此操作,但它會使所有圖標出現並在JPanel
渲染后立即開始它們的動作。 我希望他們在隨機時間出現/開始他們的動作,我考慮過實施第二個timer
,每 10 秒創建一個隨機數 - 1 或 2 - (例如,如果數字等於 1,它會為此啟動 animation特定圖標)。
Timer timer;
....
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(world_map,0,0, getWidth(), getHeight(), null);
for (Transportation item : transportations) {
item.drawTransportation(g);
g2d.drawLine(item.start_x+25,item.start_y+25,item.finish_x+25,item.finish_y+25);
}
}
@Override
public void actionPerformed(ActionEvent e) {
for (Transportation item : transportations) {
if (item.x > item.finish_x) {
item.x -= 1;
}
else if (item.x < item.finish_x) {
item.x += 1;
}
if (item.y > item.finish_y) {
item.y -= 1;
}
else if (item.y < item.finish_y) {
item.y += 1;
}
}
repaint();
}
public void startCoords() {
for (Transportation item : transportations) {
item.setMap_coords(map_coords);
item.setCountries(countries);
}
timer = new Timer(10,this);
timer.start();
}
“一般”來說,多個 Swing Timer
不能很好地擴展。 而且,如果您正在嘗試開發某種游戲,那么將所有“更新”保持在一個“游戲循環”中會在控制事情方面增加很多好處。
所以,這是一個非常簡單的概念。 當Timer
滴答作響時,它會檢查已經過去的時間量,當達到某種增量時,它會生成一堆“隨機事物”。
我還放了一個小計數器,這樣您就可以看到沿途實際上仍在發生某些事情。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private List<Point> points = new ArrayList<>(25);
private Timer timer;
private Instant clock;
private Random rnd = new Random();
public TestPane() {
setBackground(Color.BLACK);
setForeground(Color.WHITE);
timer = new Timer(5, new ActionListener() {
private Instant anchorTime;
@Override
public void actionPerformed(ActionEvent arg0) {
if (anchorTime == null) {
anchorTime = Instant.now();
}
// You could just do a mod 10, but I'm feeling lazy
if (Duration.between(anchorTime, Instant.now()).getSeconds() >= 10) {
anchorTime = Instant.now();
generateRandomThing();
}
repaint();
}
});
timer.setInitialDelay(0);
clock = Instant.now();
}
protected void generateRandomThing() {
for (int index = 0; index < 10; index++) {
int x = 10 + (int) (rnd.nextDouble() * (getWidth() - 20));
int y = 10 + (int) (rnd.nextDouble() * (getHeight() - 20));
Point p = new Point(x, y);
points.add(p);
}
}
@Override
public void addNotify() {
super.addNotify();
clock = Instant.now();
timer.start();
}
@Override
public void removeNotify() {
super.removeNotify(); //To change body of generated methods, choose Tools | Templates.
timer.stop();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Duration runTime = Duration.between(clock, Instant.now());
g2d.setColor(Color.WHITE);
FontMetrics fm = g2d.getFontMetrics();
String text = Long.toString(runTime.getSeconds());
int x = 10;
int y = 10 + fm.getAscent();
g2d.drawString(text, x, y);
g2d.setColor(Color.RED);
for (Point p : points) {
g2d.fillOval(p.x - 5, p.y - 5, 10, 10);
}
g2d.dispose();
}
}
}
這絕不是您可以采取的唯一方法,它只是可擴展性和控制的問題之一。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.