i can't see circle moving

后端 未结 2 649
忘了有多久
忘了有多久 2021-01-29 05:26

While using Swing in java, I am trying to move a circle slowly from a starting position to an end position when clicking a button. However, I can\'t see the circle moving. It ju

2条回答
  •  说谎
    说谎 (楼主)
    2021-01-29 05:47

    As said in the comments and another answer, don't block the EDT. Thead.sleep(...) will block it, so you have two options:

    • Create and manage your own (new) thread.
    • Use a Swing Timer

    In this answer I'll be using a Swing Timer, since it's easier to use. I also changed the paintComponent method to use the Shape API and change the button text to start and stop accordingly as well as reusing the same ActionListener for the button and the timer:

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.ActionListener;
    import java.awt.geom.Ellipse2D;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    
    public class MovingCircle {
        private JFrame frame;
        private CustomCircle circle;
        private Timer timer;
        private JButton button;
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new MovingCircle()::createAndShowGui);
        }
    
        private void createAndShowGui() {
            frame = new JFrame(this.getClass().getSimpleName());
            circle = new CustomCircle(Color.RED);
            timer = new Timer(100, listener);
            button = new JButton("Start");
            button.addActionListener(listener);
    
            circle.setBackground(Color.WHITE);
            frame.add(circle);
            frame.add(button, BorderLayout.SOUTH);
            frame.pack();
            frame.setVisible(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    
        private ActionListener listener = (e -> {
            if (!timer.isRunning()) {
                timer.start();
                button.setText("Stop");
            } else {
                if (e.getSource().equals(button)) {
                    timer.stop();
                    button.setText("Start");
                }
            }
            circle.move(1, 1);
        });
    
        @SuppressWarnings("serial")
        class CustomCircle extends JPanel {
            private Color color;
            private int circleX;
            private int circleY;
    
            public CustomCircle(Color color) {
                this.color = color;
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                g2d.setColor(color);
                g2d.fill(new Ellipse2D.Double(circleX, circleY, 50, 50));
            }
    
            @Override
            public Dimension preferredSize() {
                return new Dimension(100, 100);
            }
    
            public void move(int xGap, int yGap) {
                circleX += xGap;
                circleY += yGap;
                revalidate();
                repaint();
            }
    
            public int getCircleX() {
                return circleX;
            }
    
            public void setCircleX(int circleX) {
                this.circleX = circleX;
            }
    
            public int getCircleY() {
                return circleY;
            }
    
            public void setCircleY(int circleY) {
                this.circleY = circleY;
            }
        }
    }
    

    I'm sorry, I can't post a GIF as I wanted but this example runs as expected.

提交回复
热议问题