Search code examples
javascalatreeviewjavafx-2scalafx

CustomTreeItem using nodes instead of String


[EDIT]: I managed to go around my problem but I am still looking for a better solution. My solution is posted below.

I am relatively new to Scala as well ScalaFX but I've worked with JavaFX before. I am trying to create a TreeView with custom rows that use HBoxes.

This is what I want to create: Image displaying a TreeView

As you can see the TreeView uses both text as Strings but also Nodes (Statusbar, labels, hyperlinks/buttons). When I set the value of the TreeItem to a Node it uses the toString function to print the string representation but I want it to show the actual Nodes.

String representation of the Node

I know that I can override the toString function but I have no use of this because I want the Nodes to show, not just text.

This is a sample code I put together:

import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.collections.ObservableBuffer
import scalafx.scene.{Scene}
import scalafx.scene.control.{TreeItem, TreeView}
import scalafx.scene.layout.{BorderPane, HBox}

object Launcher extends JFXApp {

  case class Picture(path : String, fileSize : Double, isRoot : Boolean,
                     picChildren : Seq[Picture])

  case class PictureRow(picture: Picture) extends HBox

  val childList = Seq(
    new Picture("/Users/lindberg/Desktop/download.jpeg", 1.4, isRoot = false, Nil),
    new Picture("/Users/lindberg/Desktop/image5.jpeg", 0.5, isRoot = false, Nil)
  )

  val rootList = Seq(
    new Picture("/Users/lindberg/Desktop/", 0, isRoot = true, childList)
  )


  val treeView = new TreeView[PictureRow]() {
    root = new TreeItem[PictureRow]() {
      children = ObservableBuffer(rootList.map(n => makeTreeItem(n)))
      expanded = true
    }
    showRoot = false
  }

  val scene = new Scene(800, 400)

  scene.root = new BorderPane {
    center = treeView
  }

  stage = new PrimaryStage()

  stage.scene = scene

  def makeTreeItem(picture : Picture): TreeItem[PictureRow] = {
    val item = new TreeItem[PictureRow]() {
      children = ObservableBuffer(picture.picChildren.map(n => makeTreeItem(n)))
      expanded = true
      value = PictureRow(picture)
    }
    item
  }
}

[EDIT]: This is a solution that went around the problem but it is still not a good solution so I'd like some help with this if anyone is interested.

Solution: I overrided the toString function to return an empty String and I added a Pane as a graphics node to the TreeItem. This pane was then filled with all nodes that I wanted to be in the row.


Solution

  • This is a solution that went around the problem but it is still not a good solution so I'd like some help with this if anyone is interested.

    Solution: Because the TreeView doesn't show the graphics of the TreeItem if the value is null I then overrided the toString function to return an empty String. Now the graphics are shown and afterwards there is an empty String "" than is invisible. I added a Pane as a graphics node to the TreeItem. This pane was then filled with all nodes that I wanted to be in the row.