0

I have a tableview and in one column I would like to be able to indvidually color each character of the string. Apparently, textFill only works on the entire cell, as I did try splitting the string by characters first. I've included the code below which does not quite do as I wish, but is indicative (it changes the cell text color based only upon the first character). How can I adjust to get a multicolored output in that cell? [note: the unicode characters are up and down arrows]

    val colTick = new TableColumn[Quote, String] {
      editable = false
      text = "Tick"
      prefWidth = 90
      alignmentInParent = scalafx.geometry.Pos.Center
      cellFactory = { _ =>
        new TableCell[Quote, String] {
          item.onChange { (_, _oldTick, newTick) =>
            if (newTick == null) {
              text = null
              graphic = null
            } else {
              if (newTick(0) == '\u2B06') {
                textFill = Color.Green
              } else {
                if (newTick(0) == '\u2B07') textFill = Color.Red else textFill = Color.Black
              }
              text = newTick
            }
          }
        }
      }
      cellValueFactory = {
        _.value.tick
      }
    }
TrustNoOne
  • 585
  • 1
  • 5
  • 15

2 Answers2

1

One option is to use separate Text for each character, so you can set its color individually. Then combine those Texts in HBox, TextFlow or whatever is suitable. Here is an example where characters r, g, and b will be in color, other characters in black:

cellFactory = { _ =>
  new javafx.scene.control.TableCell[Quote, String] {
    override def updateItem(item: String, empty: Boolean): Unit = {
      super.updateItem(item, empty)
      setText(null)
      if (item == null || empty) {
        setGraphic(null)
      } else {
        val texts = item.map { c =>
          val color: Color = c.toLower match {
            case 'r' => Color.Red
            case 'g' => Color.Green
            case 'b' => Color.Blue
            case _ => Color.Black
          }
          new Text {
            text = c.toString
            fill = color
          }
        }
        setGraphic(new HBox(texts: _*))
      }
    }
  }
}
Jarek
  • 1,513
  • 9
  • 16
  • Thank you for pointing me in the proper direction. However, the override was being rejected. The key things though were the Text type and the Hbox. I've posted the working fragment for comparison. – TrustNoOne Jan 21 '17 at 05:25
0

Starting from remarks given by @Jarek, this code seems to work now:

      cellFactory = { _ =>
        new TableCell[Quote, String] {
          item.onChange { (_, _oldTick, newTick) =>
            if (newTick == null) {
              text = null
              graphic = null
            } else {
              val texts = newTick.map { c =>
                val color: Color = c match {
                  case '⬇' => Color.Red
                  case '⬆' => Color.Green
                  case '_' => Color.Crimson
                  case '○' => Color.DarkBlue
                  case _ =>Color.Black
                }
                new Text {
                  setText(c.toString)
                  setFill(color)
                }

              }
              graphic = new javafx.scene.layout.HBox(texts: _*)
            }
          }
        }
      }
TrustNoOne
  • 585
  • 1
  • 5
  • 15