簡體   English   中英

如何在 Java Swing 中實現多個定時器

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM