Swing rate limiting

后端 未结 1 1225
灰色年华
灰色年华 2020-12-18 12:58

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 unsat

相关标签:
1条回答
  • 2020-12-18 13:38

    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);
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题