How do I stop my paint method form repeating twice?

后端 未结 1 839
野的像风
野的像风 2020-12-21 23:46

Here is the code for a dice game that I am working on that outputs the results to a window. The paint method repeats twice, which is not good for me because I want the dice

相关标签:
1条回答
  • 2020-12-22 00:21
    • The short answer is - you can't. You don't control when painting occurs that is the domain of the RepaintManager.
    • You should also NEVER call Thread.sleep within the context of the Event Dispatching Thread and especially not within any paint method
    • You should avoid overriding paint and instead use paintComponent
    • You should avoid extending from JFrame and instead use something like JPanel, which actually has a paintComponent method.
    • Animation of this nature is best achieved by using a Swing Timer, which will allow to employee a pause which is maintained outside of the EDT, but is triggered again within in the EDT making it safer to perform painting and updates

    Take a look at

    • Concurrency in Swing
    • How to Use Swing Timers
    • Performing Custom Painting
    • Painting in AWT and Swing

    For more details about how painting works in Swing and how to achieve what you are trying to do

    Updated with working example

    Snake Eyes

    Cause I'm lazy, I've utilised the Graphics 2D API to draw the dots. I did this because many of the dots appear in the same locations for many of the numbers...

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Shape;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.geom.Ellipse2D;
    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class DiceRoller {
    
        public static void main(String[] args) {
            new DiceRoller();
        }
    
        public DiceRoller() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new Die());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class Die extends JPanel {
    
            private int number = 1;
    
            public Die() {
                Timer timer = new Timer(500, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        number = (int) (Math.round((Math.random() * 5) + 1));
                        repaint();
                    }
                });
                timer.setRepeats(true);
                timer.setInitialDelay(0);
                timer.start();
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(220, 220);
            }
    
            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                int width = getWidth();
                int height = getHeight();
    
                g2d.setColor(Color.WHITE);
                g2d.fillRect(0, 0, width, height);
                g2d.setColor(Color.BLACK);
                g2d.drawRoundRect(10, 10, width - 20, height - 20, 50, 50);
    
                List<Shape> dots = new ArrayList<>(6);
    
                if (number == 1 || number == 3 || number == 5) {
                    int x = (width - 20) / 2;
                    int y = (height - 20) / 2;
                    dots.add(new Ellipse2D.Float(x, y, 20, 20));
                }
    
                if (number == 2 || number == 3 || number == 4 || number == 5 || number == 6) {
    
                    int x = ((width / 2) - 20) / 2;
                    int y = ((height / 2) - 20) / 2;
                    dots.add(new Ellipse2D.Float(x, y, 20, 20));
                    dots.add(new Ellipse2D.Float(x + (width / 2), y + (height / 2), 20, 20));
    
                }
    
                if (number == 4 || number == 5 || number == 6) {
    
                    int x = (width / 2) + (((width / 2) - 20) / 2);
                    int y = ((height / 2) - 20) / 2;
                    dots.add(new Ellipse2D.Float(x, y, 20, 20));
                    dots.add(new Ellipse2D.Float(x - (width / 2), y + (height / 2), 20, 20));
    
                }
    
                if (number == 6) {
    
                    int x = (((width / 2) - 20) / 2);
                    int y = (height - 20) / 2;
                    dots.add(new Ellipse2D.Float(x, y, 20, 20));
                    dots.add(new Ellipse2D.Float(x + (width / 2), y, 20, 20));
    
                }
    
                for (Shape dot : dots) {
                    g2d.fill(dot);
                }
    
                g2d.dispose();
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题