Я хотел бы создать вид (сцена, окно) с частично прозрачным фоном. У меня есть изображение, содержащее альфа-канал
Я использовал такие сцены в JavaFx, где мне нужно было установить для заливки сцены значение null, а цвет фона корневого узла — прозрачный. Я попробовал то же самое с TornadoFX:
class NextRoundView : View("Következő kör") {
override val root = vbox {
style {
backgroundColor = multi(Color.TRANSPARENT)
backgroundImage = multi(URI.create("/common/rope-bg-500x300.png"))
backgroundRepeat = multi(BackgroundRepeat.NO_REPEAT
to BackgroundRepeat.NO_REPEAT)
}
prefWidth = 500.0
prefHeight = 300.0
spacing = 20.0
padding = insets(50, 20)
text("A text") {
font = Font.font(40.0)
alignment = Pos.CENTER
}
button("OK")
{
font = Font.font(20.0)
action {
close()
}
}
sceneProperty().addListener{ _,_,n ->
n.fill = null
}
}
}
Я вызываю представление следующим образом:
NextRoundView().apply {
openModal(stageStyle = StageStyle.TRANSPARENT, block = true)
}
Однако у сцены все еще есть предыстория:
Что я пропустил?





Вы сделали пару ошибок, которые вызывают это. Прежде всего, вы никогда не должны вручную создавать экземпляры UICompoenents (View, Fragment). Это заставит их пропустить важные обратные вызовы жизненного цикла. Одним из важных обратных вызовов является onDock, который является идеальным местом для управления назначенной сценой. Изменение этих двух проблем, а также очистка синтаксиса приводит к следующему коду, который успешно делает фон прозрачным:
class MyApp : App(MyView::class)
class MyView : View() {
override val root = stackpane {
button("open").action {
find<NextRoundView>().openModal(stageStyle = StageStyle.TRANSPARENT, block = true)
}
}
}
class NextRoundView : View("Következő kör") {
override val root = vbox {
style {
backgroundColor += Color.TRANSPARENT
backgroundImage += URI.create("/common/rope-bg-500x300.png")
backgroundRepeat += BackgroundRepeat.NO_REPEAT to BackgroundRepeat.NO_REPEAT
}
prefWidth = 500.0
prefHeight = 300.0
spacing = 20.0
padding = insets(50, 20)
text("A text") {
font = Font.font(40.0)
alignment = Pos.CENTER
}
button("OK") {
font = Font.font(20.0)
action {
close()
}
}
}
override fun onDock() {
currentStage?.scene?.fill = null
}
}
Вот скриншот приложения с внесенными изменениями:
Вау! Этот ответ был очень полезен для меня. Помимо того, что это решило мою проблему, оно также научило меня нескольким другим вещам, таким как использование стиля += вместо multi(), правильному вызову представлений и тому, где манипулировать сценой. Большое спасибо!