public BallsFrame() throws HeadlessException {
   super("Funny balls");
   setLayout(new BorderLayout());
   executorService = Executors.newScheduledThreadPool(1);
   ballsPanel =
       new JPanel() {
         @Override
         protected void paintComponent(Graphics g) {
           super.paintComponent(g);
           if (blueBallVisible) {
             g.setColor(Color.BLUE);
             g.fillOval(blueBall.x, getHeight() / 2, BALL_DIAGONAL, BALL_DIAGONAL);
           }
           g.setColor(Color.RED);
           g.fillOval(redBall.x, getHeight() / 2, BALL_DIAGONAL, BALL_DIAGONAL);
         }
       };
   add(ballsPanel, BorderLayout.CENTER);
   blueBallSwitch = new JCheckBox("Collision", true);
   blueBallSwitch.addItemListener(
       e -> {
         if (blueBallVisible = blueBallSwitch.isSelected()) {
           int x;
           do x = random.nextInt(getWidth() - BALL_DIAGONAL);
           while (redBall.x <= x && x <= redBall.rightX()
               || redBall.x <= x + BALL_DIAGONAL && x + BALL_DIAGONAL <= redBall.rightX());
           blueBall.x = x;
         }
       });
   add(blueBallSwitch, BorderLayout.SOUTH);
   blueBallVisible = true;
   moveToRight = true;
   setSize(500, 500);
 }
 private void startAnimation() {
   redBall = new Ball(1);
   blueBall = new Ball(getWidth() / 2);
   executorService.scheduleAtFixedRate(
       () -> {
         if (redBall.rightX() >= getWidth()
             || redBall.x <= 0
             || blueBallVisible && redBall.intersectsWith(blueBall)) moveToRight = !moveToRight;
         redBall.x += moveToRight ? 1 : -1;
         ballsPanel.repaint();
       },
       1,
       5,
       TimeUnit.MILLISECONDS);
 }
 public boolean intersectsWith(Ball other) {
   return this.x <= other.x && other.x <= this.rightX()
       || this.x <= other.rightX() && other.rightX() <= this.rightX();
 }