Question

I want to change the background colour of a custom TreeCell using CSS, but setting the style property on the tree cell doesn't work. I can style the tree with alternate yellow and grey cells with a CSS file that looks like this:

.tree-cell:disabled {
    -fx-padding: 3 3 3 3;
    -fx-background-color: white;
}

.tree-cell:selected {
    -fx-background-color: blue;
}

.tree-cell:even {
    -fx-background-color: yellow;
}

.tree-cell:odd {
    -fx-background-color: grey;
}

.tree-cell:drag-over {
    -fx-background-color: plum;
}

and change the fill style of the text with an event handler that looks like this:

  onDragEntered = (event: DragEvent) => {
    val db = event.getDragboard
    if (db.hasContent(customFormat)) {
      textFill = Color.DEEPSKYBLUE

      style() = "tree-cell:drag-over"
    }

    event.consume()
  }

but the style of the tree cells doesn't change.

Was it helpful?

Solution

I eventually found the answer to my own question. The CSS file now looks like this:

.tree-cell:disabled {
    -fx-padding: 3 3 3 3;
    -fx-background-color: white;
}

.tree-cell:selected {
    -fx-background-color: blue;
}

.tree-cell:filled:even {
    -fx-background-color: lightyellow;
}

.tree-cell:filled:odd {
    -fx-background-color: lightsteelblue;
}

.tree-cell.drag-over:filled {
    -fx-background-color: plum;
}

I now get a plum colour when dragging over a filled cell. Empty cells stay white. In order to get here I needed to understand the rules of "CSS specificity", although it was eventually possible to simplify the finished CSS file to make each case exactly match one selector.

The ScalaFX code now looks like this:

import scala.collection.JavaConversions._

// Copy the list, so that it isn't modified in place.
var oldStyleClass: util.Collection[String] = styleClass.toList

onDragEntered = (event: DragEvent) => {
  val db = event.getDragboard
  if (db.hasContent(customFormat)) {
    textFill = Color.DEEPSKYBLUE

    // Remember the original style by taking a copy.
    oldStyleClass = styleClass.toList

    // Restyle filled cells with .tree-cell.dragover:filled
    // for the duration of the drag
    styleClass.add("drag-over")
  }

  event.consume()
}

onDragExited = (event: DragEvent) => {
  val db = event.getDragboard
  if (db.hasContent(customFormat)) {
    textFill = Color.BLACK
  }

  // Restore the original style.
  styleClass.setAll(oldStyleClass)

  event.consume()
}

Somewhere along the way I lost the animation for a failed drop. Otherwise I'm happy (but somewhat lonely in ScalaFX-land.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top