1  import javafx.animation.KeyFrame;
  2  import javafx.animation.Timeline;
  3  import javafx.beans.property.DoubleProperty;
  4  import javafx.scene.layout.Pane;
  5  import javafx.scene.paint.Color;
  6  import javafx.scene.shape.Circle;
  7  import javafx.util.Duration;
  8  
  9  public class BallPane extends Pane {
 10    public final double radius = 20;
 11    private double x = radius, y = radius;
 12    private double dx = 1, dy = 1;
 13    private Circle circle = new Circle(x, y, radius);
 14    private Timeline animation;
 15  
 16    public BallPane() {
 17      circle.setFill(Color.GREEN); // Set ball color
 18      getChildren().add(circle); // Place a ball into this pane
 19  
 20      // Create an animation for moving the ball
 21      animation = new Timeline(
 22        new KeyFrame(Duration.millis(50), e -> moveBall()));
 23      animation.setCycleCount(Timeline.INDEFINITE);
 24      animation.play(); // Start animation
 25    }
 26  
 27    public void play() {
 28      animation.play();
 29    }
 30  
 31    public void pause() {
 32      animation.pause();
 33    }
 34  
 35    public void increaseSpeed() {
 36      animation.setRate(animation.getRate() + 0.1);
 37    }
 38  
 39    public void decreaseSpeed() {
 40      animation.setRate(
 41        animation.getRate() > 0 ? animation.getRate() - 0.1 : 0);
 42    }
 43  
 44    public DoubleProperty rateProperty() {
 45      return animation.rateProperty();
 46    }
 47    
 48    protected void moveBall() {
 49      // Check boundaries
 50      if (x < radius || x > getWidth() - radius) {
 51        dx *= -1; // Change ball move direction
 52      }
 53      if (y < radius || y > getHeight() - radius) {
 54        dy *= -1; // Change ball move direction
 55      }
 56  
 57      // Adjust ball position
 58      x += dx;
 59      y += dy;
 60      circle.setCenterX(x);
 61      circle.setCenterY(y);
 62    }
 63  }