A example of how flexible can be extending your own Custom Node. In this example I’m creating a comic ballon that can be simple created by:
Ballon { text: "I can has fx?" }
That can also be incremented to work like this:
[youtube:http://br.youtube.com/watch?v=LexJbO1-ti4]
Here a simpler implementation of a balloon, without the dragging behavior but that can be used for creating comics.
import javafx.scene.CustomNode;
import javafx.scene.Group;
import javafx.scene.geometry.Ellipse;
import javafx.scene.geometry.Polygon;
import javafx.scene.geometry.ShapeSubtract;
import javafx.scene.paint.Color;
import javafx.scene.Font;
import javafx.scene.text.Text;
import javafx.scene.FontStyle;
import java.lang.Math;
public class Balloon extends CustomNode {
/* (cx,cy) center of the balloon */
public attribute cx: Number = 100 on replace {
distance = Math.sqrt(toX * toX + toY * toY);
}
public attribute cy: Number = 100 on replace {
distance = Math.sqrt(toX * toX + toY * toY);
}
/* (toX, toY) point where balloon points at */
public attribute toX: Number = cx on replace {
distance = Math.sqrt(toX * toX + toY * toY);
}
public attribute toY: Number = cy on replace {
distance = Math.sqrt(toX * toX + toY * toY);
}
/* what is writted in the balloon */
public attribute text: String = "balloon";
/* font for the text */
public attribute font: Font = Font {
size: 24
style: FontStyle.PLAIN
}
/* Distance between (cx,cy) and (toX, toY) */
private attribute distance: Number;
/* Text inside the balloon */
private attribute label = Text {
font: bind font
content: bind text
}
/* place the label correctly based on text */
init {
label.x = -label .getWidth() / 2;
label.y = label.font.size / 2;
}
/* ballon body */
private attribute body = ShapeSubtract{
fill: Color.WHITE
stroke: Color.BLACK
blocksMouse: true
a: bind [
Ellipse {
radiusX: bind label.getWidth() / 2 + 20
radiusY: bind font.size * 2
},
Polygon {
points : [
10 * ( - toY / distance),
10 * (toX / distance),
10 * (toY / distance),
10 * ( - toX / distance),
toX,
toY
]
}
]
}
public function create(): Node {
return Group {
cursor: Cursor.HAND
content: [ body, label]
translateX: bind cx
translateY: bind cy
}
}
}