Search code examples
csskotlinjavafxtornadofx

Removing background image from label in tornadofx


I have two css classes on a tornadofx label bound to a SimpleBooleanProperty. One which has a background image and a blue border and one which has no background image and a yellow border.

Snippet from View containing label:

val switch: SimpleBooleanProperty = SimpleBooleanProperty(false)

label("my label"){
   toggleClass(UIAppStyle.style1, switch.not())
   toggleClass(UIAppStyle.style2, switch)
}

Snippet from UIAppStyle:

s(style1){
   textFill = Color.YELLOW
   maxWidth = infinity
   maxHeight = infinity
   alignment = Pos.CENTER

   backgroundImage += this::class.java.classLoader.getResource("img.png")!!.toURI()
   backgroundPosition += BackgroundPosition.CENTER
   backgroundRepeat += Pair(BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT)
   borderColor += box(Color.BLUE)
}
s(style2){
   textFill = Color.YELLOW
   maxWidth = infinity
   maxHeight = infinity
   alignment = Pos.CENTER
   borderColor += box(Color.YELLOW)
}

When switch = false, there is a background image and a blue border. When switch = true, there is the same background image and a yellow border. I'm not finding out how to get the background image to remove. Interestingly enough, if I add a different background image to style2, it changes correctly.

Edit: To remove two toggleClasses and introduce new strange problem:

class MyView : View(){
...
init{
   ...
   row{
      repeat(myviewmodel.numSwitches){
         val switch = myviewmodel.switches[it]
         val notSwitch = switch.not()
         label("my label"){
            addClass(UIAppStyle.style2)
            toggleClass(UIAppStyle.style1, notSwitch)
         }
      }
   }
}

This code snippet does not work for me. However, if I add private var throwsArray = mutableListOf<ObservableValue<Boolean>>() as a field of MyView and add notSwitch to the array, then the same exact code works. It's almost as if notSwitch is going out of scope and becoming invalidated unless I add it to a local array in the class?


Solution

  • Edited to do inverse of status

    Here is simple example of a working toggle class using your styling:

    class TestView : View() {
        override val root = vbox {
            val status = SimpleBooleanProperty(false)
    
            label("This is a label") {
                addClass(UIAppStyle.base_cell)
                val notStatus = SimpleBooleanProperty(!status.value)
                status.onChange { notStatus.value = !it } // More consistent than a not() binding for some reason
                toggleClass(UIAppStyle.smiling_cell, notStatus)
            }
            button("Toggle").action { status.value = !status.value }
        }
    
        init {
            importStylesheet<UIAppStyle>()
        }
    }
    

    As you can see, the base class is added as the default, while styling with the image is in the toggle class (no not() binding). Like mentioned in other comments, the toggleClass is picky, additive in nature, and quiet in failure so it can sometimes be confusing.

    FYI I got to this only by going through your github code and I can say with confidence that the not() binding is what screwed you in regards to the toggleClass behaviour. Everything else causing an error is related to other problems with the code. Feel free to ask in the comments or post another question.