Grafické API v JavaFX obsahuje atributy pro zjišťování hranic (bounds) jednotlivých elementů ve scéně. Toto API je na první pohled docela jednoduché, ale při intenzivnějším používání se objevují mnohé záludnosti. Jedním vhodným použitím hranic elementu je vytvoření přizůsobivého pozadí. Jinými slovy jde o element, který svojí plochou pokrývá plochu jiného elementu a vykresluje se pod ním.
Začněme jednoduchým kódem, který obsahuje VBox (stará se o vertikální zarovnání elementů pod sebe), do kterého je možné přídávat a odebírat prvky.
var nodes: Node[] = [];
var box: VBox;
Stage {
title: "Background Fill"
scene: Scene {
width: 240
height: 320
content: [
box = VBox {
content: bind nodes
spacing: 10
onKeyPressed: function(e) {
if (e.code == KeyCode.VK_UP) {
insert
Rectangle {
width: 50
height: 50
fill: Color.GREEN
} into nodes;
}
if (e.code == KeyCode.VK_DOWN) {
if (sizeof(nodes) > 0) {
delete nodes[0] from nodes;
}
}
}
}
]
}
}
Jediným správným místem kam pozadí umístit je na stejnou úroveň jako je vbox s elementy. Tím, že se element pro pozadí umístí do obsahu před vbox se zajistí, že se bude vykreslovat pod ním.
content: [
Rectangle {
x: 0
y: 0
width: 240
height: 320
fill: Color.YELLOW
},
box = VBox {
// beze změny
}
]
Takto se ale vytvoří pouze obdélník, který zakrývá pevně danou plochu 240×320. Aby kopíroval rozměry vboxu, kterému má být pozadím, je třeba jeho rozměry provázat s hranicemi vboxu. K tomu poslouží bind a boundsInParent.
Rectangle {
x: 0
y: 0
width: bind box.boundsInParent.width
height: bind box.boundsInParent.height
fill: Color.RED
}
Takhle kód funguje dobře a dělá přesně to, co se po něm chce. Vzhledově to ale moc dobře nevypadá, je dobré například přidat nějaké okraje:
var nodes: Node[] = [];
var box: VBox;
def MARGIN = 5;
Stage {
title: "Background Fill"
scene: Scene {
width: 240
height: 320
content: [
Rectangle {
x: bind box.boundsInParent.minX - MARGIN
y: bind box.boundsInParent.minY - MARGIN
width: bind box.boundsInParent.width + MARGIN*2
height: bind box.boundsInParent.height + MARGIN*2
fill: Color.RED
},
box = VBox {
content: bind nodes
spacing: 2*MARGIN
translateX: MARGIN // Odsazení od kraje
translateY: MARGIN // Odsazení od kraje
onKeyPressed: function(e) {
if (e.code == KeyCode.VK_UP) {
insert
Rectangle {
width: 50
height: 50
fill: Color.GREEN
} into nodes;
}
if (e.code == KeyCode.VK_DOWN) {
if (sizeof(nodes) > 0) {
delete nodes[0] from nodes;
}
}
}
}
]
}
}
box.requestFocus();
Výsledná aplikace pak vypadá takto:
Kód je k dispozici na githubu: prizpusobive-pozadi