Some more JavaFX surprises
Playing around with JavaFX and reading some more in the [scarce] documentation, I found the following neat tricks:
- Expressions within quoted text: In JavaFX you can use variable and attribute names inside quoted strings, such as if you had a variable called
namewith the value "Aviad", the following quoted string:"Name: {name}"would be parsed (and printed out if used as output) to be"Name: Aviad". The neat part is that expressions can be used inside the curly brackets, and evenif .. then .. elseconstructs. - Automatic Nested Loops: In JavaFX you can create a nested loop by just specifying the second (or third or nth) loop in the
forconstruct. Example for writing the multiplication table:import java.lang.*; import javafx.ui.*; import javafx.ui.canvas.*; Canvas { content: bind foreach (i in [1..10], j in [1..10]) { Text { content: "{i*j}" x:i * 30 y:j * 30} } } - Quick Animations: You can quickly create animations by using the operator
dur(from "duration"). When assigning any value with an array of possible values and the operatordur, JavaFX will create a background thread (or, more likely, push events into the AWT event queue) which will assign the range of values into the variable. By binding the location, size or transformation of a graphical element, this can create a smooth animation. Try the following example for a cube which escapes when approached with the mouse cursor:import javafx.ui.*; import javafx.ui.canvas.*; import java.lang.Math; class EscapingRect extends CompositeNode { attribute x: Number; attribute y: Number; attribute size: Number; operation runAway(); } function EscapingRect.composeNode() = Rect { x: bind x y: bind y width: bind size height: bind size fill: red onMouseEntered: operation(e:CanvasMouseEvent) { runAway(); } }; operation EscapingRect.runAway() { var xDir = if Math.random() > 0.5 then 1 else -1; var yDir = if Math.random() > 0.5 then 1 else -1; x = [x..x+Math.random()*100 * xDir] dur 500; y = [y..y+Math.random()*100 * yDir] dur 500; } Canvas { content: EscapingRect { x: 100 y: 100 size: 100 } }
Comments (16)
getCanvas()method, and then it should be able to access thecontentattribute. I suppose that if you create a function in a composite node that does something withgetCanvas().content, and then assign the function toButton'sactionattribute (for example), it might work - but I haven't tried it. See if it works and let me know!