添加 child 到 borderpane center resizes button in top
Adding child to borderpane center resizes button in top
我目前正在将 JavaFx 应用程序迁移到 TornadoFx。我想在单击按钮时添加一个图表。我最终得到以下 stripped-down 代码:
borderpane {
prefWidth = 1000.0
prefHeight = 750.0
padding = insets(10)
top = vbox {
spacing = 5.0
hbox {
spacing = 5.0
alignment = Pos.CENTER_LEFT
button("Show") {
action {
val centerRef = this@borderpane.center as VBox
println(centerRef.id)
if (centerRef.children.size > 0)
centerRef.children.removeAll(centerRef.children)
val seriesData = (1..25)
.map { Random().nextDouble() }
.zip((1..25).map { Random().nextDouble() })
.toMap()
centerRef.add(linechart("My Chart", NumberAxis(), NumberAxis()) {
series("my series") {
for ((k,v) in seriesData) {
data(k, v)
}
}
})
}
}
}
separator()
}
center = vbox { id = "centervbox" }
}
不幸的是,一旦事件被触发,按钮的大小就会被调整。我试图设置按钮的最大宽度和高度,但设置被忽略了。我是 Kotlin 和 TornadoFx 的新手(虽然有一些 JavaFx 经验),非常感谢任何建议。
在此先致谢并致以亲切的问候。
编辑:我在这段代码中遇到了同样奇怪的行为,即第一个图表放置在按钮内。只有在第二次单击后图表才能正确添加到 VBox。
vbox {
prefWidth = 1000.0
prefHeight = 750.0
id = "rootvbox"
button("button1") {
action {
val vbRef = this@vbox
println(vbRef.id)
val lc = linechart("My Chart", NumberAxis(), NumberAxis()) {
series("my series") {
for ((k,v) in (1..25).map { Random().nextDouble() }.zip((1..25).map { Random().nextDouble() }).toMap()) {
data(k, v)
}
}
}
vbRef.children.add(lc)
}
}
您不小心将折线图添加到了您的按钮中。了解构建器的工作原理非常重要 - 如果您调用构建器函数,例如在节点上调用 linechart()
,新组件将添加到该节点。所以你在这里做:
button("Show") {
action {
centerRef.add(linechart(...))
}
}
这是告诉框架在按钮内部创建一个折线图,然后将其添加到 centerRef。您实际上是在呼叫 this@button.linechart()
。建造者的工作不仅仅是建造元素,还要将它附加到它的父元素上。因此,您只需调用 centerRef.linechart(..)
即可解决您的问题。
您应该尽量避免依赖其他 UI 元素,并尽可能减少组件之间的引用。以下示例使用事件来减少耦合:
// An event containing a builder that will construct the chart inside the given Node
class ChartAddEvent(val builder: Node.() -> Unit) : FXEvent()
class MainView : View() {
override val root = borderpane {
setPrefSize(1000.0, 750.0)
paddingAll = 10
top = hbox(5) {
// Call the addChart function
button("Show").action(::addChart)
}
center = vbox {
subscribe<ChartAddEvent> { event ->
// Remove existing children
clear()
// Call the builder inside the event with the vbox as it's parent
event.builder(this@vbox)
}
}
}
// Fire a ChartAddEvent with a builder that will construct the chart
// inside a node designated by the event subscriber
private fun addChart() {
fire(ChartAddEvent {
val seriesData = (1..25)
.map { Random().nextDouble() }
.zip((1..25).map { Random().nextDouble() })
.toMap()
linechart("My Chart", NumberAxis(), NumberAxis()) {
series("my series") {
for ((k, v) in seriesData) {
data(k, v)
}
}
}
})
}
}
我目前正在将 JavaFx 应用程序迁移到 TornadoFx。我想在单击按钮时添加一个图表。我最终得到以下 stripped-down 代码:
borderpane {
prefWidth = 1000.0
prefHeight = 750.0
padding = insets(10)
top = vbox {
spacing = 5.0
hbox {
spacing = 5.0
alignment = Pos.CENTER_LEFT
button("Show") {
action {
val centerRef = this@borderpane.center as VBox
println(centerRef.id)
if (centerRef.children.size > 0)
centerRef.children.removeAll(centerRef.children)
val seriesData = (1..25)
.map { Random().nextDouble() }
.zip((1..25).map { Random().nextDouble() })
.toMap()
centerRef.add(linechart("My Chart", NumberAxis(), NumberAxis()) {
series("my series") {
for ((k,v) in seriesData) {
data(k, v)
}
}
})
}
}
}
separator()
}
center = vbox { id = "centervbox" }
}
不幸的是,一旦事件被触发,按钮的大小就会被调整。我试图设置按钮的最大宽度和高度,但设置被忽略了。我是 Kotlin 和 TornadoFx 的新手(虽然有一些 JavaFx 经验),非常感谢任何建议。
在此先致谢并致以亲切的问候。
编辑:我在这段代码中遇到了同样奇怪的行为,即第一个图表放置在按钮内。只有在第二次单击后图表才能正确添加到 VBox。
vbox {
prefWidth = 1000.0
prefHeight = 750.0
id = "rootvbox"
button("button1") {
action {
val vbRef = this@vbox
println(vbRef.id)
val lc = linechart("My Chart", NumberAxis(), NumberAxis()) {
series("my series") {
for ((k,v) in (1..25).map { Random().nextDouble() }.zip((1..25).map { Random().nextDouble() }).toMap()) {
data(k, v)
}
}
}
vbRef.children.add(lc)
}
}
您不小心将折线图添加到了您的按钮中。了解构建器的工作原理非常重要 - 如果您调用构建器函数,例如在节点上调用 linechart()
,新组件将添加到该节点。所以你在这里做:
button("Show") {
action {
centerRef.add(linechart(...))
}
}
这是告诉框架在按钮内部创建一个折线图,然后将其添加到 centerRef。您实际上是在呼叫 this@button.linechart()
。建造者的工作不仅仅是建造元素,还要将它附加到它的父元素上。因此,您只需调用 centerRef.linechart(..)
即可解决您的问题。
您应该尽量避免依赖其他 UI 元素,并尽可能减少组件之间的引用。以下示例使用事件来减少耦合:
// An event containing a builder that will construct the chart inside the given Node
class ChartAddEvent(val builder: Node.() -> Unit) : FXEvent()
class MainView : View() {
override val root = borderpane {
setPrefSize(1000.0, 750.0)
paddingAll = 10
top = hbox(5) {
// Call the addChart function
button("Show").action(::addChart)
}
center = vbox {
subscribe<ChartAddEvent> { event ->
// Remove existing children
clear()
// Call the builder inside the event with the vbox as it's parent
event.builder(this@vbox)
}
}
}
// Fire a ChartAddEvent with a builder that will construct the chart
// inside a node designated by the event subscriber
private fun addChart() {
fire(ChartAddEvent {
val seriesData = (1..25)
.map { Random().nextDouble() }
.zip((1..25).map { Random().nextDouble() })
.toMap()
linechart("My Chart", NumberAxis(), NumberAxis()) {
series("my series") {
for ((k, v) in seriesData) {
data(k, v)
}
}
}
})
}
}