Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

java - Swing rate limiting

I have a long repaint operation that I would like to rate-limit, ie make sure it gets called once every N milliseconds at most.

My current solution is somewhat unsatisfactory: I use a Swing Timer with a short duration, which I restart() whenever I get an event. This make sure that a repaint is not triggered if events happen within an N milliseconds window (i.e. the repaint will happen after an event and an N milliseconds "quiet" period has elapsed).

What I would like is to make sure the repaint is called at most N milliseconds after the first event and that the repaint period is at most N. Any ideas? (the effect of calling start on an already-started Timer is not documented).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

there as are I know only Latency that came from Native OS, if you will overflow this refresh rate then comes Error(s) from RepaintManager, btw your topic is very academic Latency is maximum refresh rate for one pixel / per seconds

but this one enter image description here

or another should be good bases for testing untill / UpTo first Error(s) comings from RepaintManager (then probably lock current JVM instance) enter image description here from code

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class AnimationBackground {

    public AnimationBackground() {
        Random random = new Random();
        JFrame frame = new JFrame("Animation Background");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.setLayout(new GridLayout(0, 1, 10, 10));
        //frame.setLayout(new GridLayout(0, 3, 10, 10));
        //for (int iPanels = 0; iPanels < 3; iPanels++) {
        for (int iPanels = 0; iPanels < 1; iPanels++) {
            final MyJPanel panel = new MyJPanel();
            panel.setBackground(Color.BLACK);
            for (int i = 0; i < 100; i++) {
                Star star = new Star(new Point(random.nextInt(490), random.nextInt(490)));
                star.setColor(new Color(100 + random.nextInt(155), 100 + random.nextInt(155), 100 + random.nextInt(155)));
                star.setxIncr(-3 + random.nextInt(7));
                star.setyIncr(-3 + random.nextInt(7));
                panel.add(star);
            }
            panel.setLayout(new GridLayout(10, 1));
            JLabel label = new JLabel("This is a Starry background.", JLabel.CENTER);
            label.setForeground(Color.WHITE);
            panel.add(label);
            JPanel stopPanel = new JPanel();
            stopPanel.setOpaque(false);
            stopPanel.add(new JButton(new AbstractAction("Stop this madness!!") {

                private static final long serialVersionUID = 1L;

                @Override
                public void actionPerformed(ActionEvent e) {
                    panel.stopAnimation();
                }
            }));
            panel.add(stopPanel);
            JPanel startPanel = new JPanel();
            startPanel.setOpaque(false);
            startPanel.add(new JButton(new AbstractAction("Start moving...") {

                private static final long serialVersionUID = 1L;

                @Override
                public void actionPerformed(ActionEvent e) {
                    panel.startAnimation();
                }
            }));
            panel.add(startPanel);
            frame.add(panel);
        }
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                AnimationBackground animationBackground = new AnimationBackground();
            }
        });
    }

    class Star extends Polygon {

        private static final long serialVersionUID = 1L;
        private Point location = null;
        private Color color = Color.YELLOW;
        private int xIncr, yIncr;
        static final int WIDTH = 500, HEIGHT = 500;

        Star(Point location) {
            int x = location.x;
            int y = location.y;
            this.location = location;
            this.addPoint(x, y + 8);
            this.addPoint(x + 8, y + 8);
            this.addPoint(x + 11, y);
            this.addPoint(x + 14, y + 8);
            this.addPoint(x + 22, y + 8);
            this.addPoint(x + 17, y + 12);
            this.addPoint(x + 21, y + 20);
            this.addPoint(x + 11, y + 14);
            this.addPoint(x + 3, y + 20);
            this.addPoint(x + 6, y + 12);
        }

        public void setColor(Color color) {
            this.color = color;
        }

        public void move() {
            if (location.x < 0 || location.x > WIDTH) {
                xIncr = -xIncr;
            }
            if (location.y < 0 || location.y > WIDTH) {
                yIncr = -yIncr;
            }
            translate(xIncr, yIncr);
            location.setLocation(location.x + xIncr, location.y + yIncr);
        }

        public void setxIncr(int xIncr) {
            this.xIncr = xIncr;
        }

        public void setyIncr(int yIncr) {
            this.yIncr = yIncr;
        }

        public Color getColor() {
            return color;
        }
    }

    class MyJPanel extends JPanel {

        private static final long serialVersionUID = 1L;
        private ArrayList<Star> stars = new ArrayList<Star>();
        private Timer timer = new Timer(20, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                for (Star star : stars) {
                    star.move();
                }
                repaint();
            }
        });

        public void stopAnimation() {
            if (timer.isRunning()) {
                timer.stop();
            }
        }

        public void startAnimation() {
            if (!timer.isRunning()) {
                timer.start();
            }
        }

        @Override
        public void addNotify() {
            super.addNotify();
            timer.start();
        }

        @Override
        public void removeNotify() {
            super.removeNotify();
            timer.stop();
        }

        MyJPanel() {
            this.setPreferredSize(new Dimension(520, 520));
        }

        public void add(Star star) {
            stars.add(star);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            for (Star star : stars) {
                g.setColor(star.getColor());
                g.fillPolygon(star);
            }
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...