import javafx.ui.canvas.*; import javafx.ui.*; import java.lang.System; import javax.swing.Timer; import java.awt.event.ActionListener; import java.awt.Toolkit; public class Ball extends Ellipse { attribute cx: Number; attribute cy: Number; attribute radiusX: Number; attribute radiusY: Number; attribute fill: Paint; attribute stroke: Paint; attribute dx: Number; attribute dy: Number; } public class BallVector { public attribute balls: Ball*; } var size = Toolkit.getDefaultToolkit().getScreenSize(); var delta = BallVector { balls: [{cx: 70, cy: 70, radiusX: 30, radiusY: 30, fill: cyan, stroke: purple, dx: 20, dy: 20}]}; var myTimer = new Timer(1, new ActionListener() { operation actionPerformed(event) { var i = 0; var width = size.width; var height = size.height; while (i < sizeof delta.balls) { if (delta.balls[i].cx < 10 or delta.balls[i].cx >= width-20) { delta.balls[i].dx = - delta.balls[i].dx; } if (delta.balls[i].cy < 10 or delta.balls[i].cy >= height-20) { delta.balls[i].dy = - delta.balls[i].dy; } delta.balls[i].cx += delta.balls[i].dx; delta.balls[i].cy += delta.balls[i].dy; i ++; } } }); Frame { var: self width: size.width height: size.height undecorated: true resizable: false disposeOnClose: true content: Canvas { var backText = Text { x: 50, y: 50, content: "JavaFX Animation using Swing Timer", font: Font {face: VERDANA, style: [ITALIC, BOLD], size: 40}, fill: LinearGradient { x1: 0, y1: 0, x2: 0, y2: 1 stops: [Stop { offset: 0 color: red }, Stop { offset: 0.5 color: maroon }, Stop { offset: 1 color: red }] } } background: RadialGradient { cx: size.width/2 cy: size.height/2 radius: size.height/2 } width: bind size.width height: bind size.height content: bind [backText, delta.balls] onMouseEntered: operation(e:MouseEvent) { myTimer.start(); } onMouseExited: operation (e:MouseEvent) { myTimer.stop(); } onMouseClicked: operation(e:MouseEvent) { if (e.button == 1.0) { var newBall = new Ball {cx: e.x, cy: e.y, radiusX: 30, radiusY: 30, fill: new Color(e.x/1000, e.y/1000, (e.x+e.y)/2000, 1), stroke: red, dx: 20, dy: 20}; insert newBall into delta.balls; return newBall; } else if (e.button == 3.0) { self.dispose = true; System.exit(0); } } } visible: true }