tableview 的某些单元格中的错误数据

Erroneous data in some cells of tableview

scala 和 scalafx 的新手,在一个简单的股票报价应用程序中遇到了 tableview 的问题[注意:没有以前的 javafx 经验,除了它类似于事物的方式 Android]

问题:(见图)错误数据显示在更改列中,而该列应该 none。

要创建:多个场景,此处显示的是新股票代码的条目。似乎无法预测有多少单元格出错。改变 window 大小(比如先短后高)通常会产生更多坏细胞。如果不更改 window 大小 and/or 符号列表,则不会发生。

下面 'ticker' 和 'change' 列的代码,尽管我怀疑这是我如何实现更改列以进行 green/red 文本着色的方式。

(注意:数据会定期单批更新,这就是新交易品种不会立即显示报价数据的原因)

      val colTicker = new TableColumn[Quote, String] {
      editable = true
      text = "Ticker"
      prefWidth = 80
      alignmentInParent = scalafx.geometry.Pos.Center
      cellValueFactory = {
        _.value.ticker
      }
      cellFactory = _ => new TextFieldTableCell[Quote, String](new DefaultStringConverter())
      onEditCommit = (evt: CellEditEvent[Quote, String]) => {
        val quote: Quote = evt.rowValue
        val newTickerVal: String = evt.newValue.toUpperCase()
        val oldTickerVal: String = evt.oldValue
        // is it a valid ticker and not a dupe or is it blank (erase old ticker)?
        if ((isValidTicker(newTickerVal) || newTickerVal.length == 0) && !symbolList.contains(newTickerVal)) {
          // lock in the new value on the screen
          quote.ticker.set(newTickerVal)
          // if the new value is not empty add it to symbol list
          if (newTickerVal.length > 0) {
            symbolList.append(newTickerVal)
          }
          // now delete the old value
          symbolList -= oldTickerVal
          // sort and add another blank line
          characters.sortWith(_.ticker.getValueSafe < _.ticker.getValueSafe)
          if (oldTickerVal.length < 1) characters += Quote()
          // now need to update the data file
          putListToFile(dataFile, symbolList.sorted)
        } else {
          // bad ticker so keep the old one and don't update file
          quote.ticker.set(oldTickerVal)
          evt.getTableView.getColumns.get(0).setVisible(false)
          evt.getTableView.getColumns.get(0).setVisible(true)
          println("bad ticker, exiting symbol list: " + symbolList)
        }
      }

    }
    val colLast = new TableColumn[Quote, String] {
      editable = false

      text = "Last"
      cellValueFactory = {
        _.value.last
      }

      prefWidth = 80
      alignmentInParent = scalafx.geometry.Pos.Center
    }
    val colChange = new TableColumn[Quote, String] {
      editable = false
      text = "Change"
      cellFactory = {
        _ =>
          new TableCell[Quote, String] {
              item.onChange { (_, _, newChange) =>
                if (newChange != null) {
                  if (newChange.toString.contains("+")) textFill = Color.Green
                  else textFill = Color.Red
                  text = newChange
                }
              }
          }
      }
      cellValueFactory = {
        _.value.change
      }
      prefWidth = 80
      alignmentInParent = scalafx.geometry.Pos.Center
    }

JavaFX 在渲染时重复使用单元格。这在动态更新 TableView 内容时尤为明显。您的 cellFactory 必须在接收和清空时清除单元格内容或 null 项:textgraphic 需要设置为 null。简单地检查 newChange == null

可能就足够了
cellFactory = { _ =>
  new TableCell[Quote, String] {
    item.onChange { (_, _, newChange) =>
      if (newChange == null) {
        text = null
        graphic = null
      else {
        if (newChange.toString.contains("+")) textFill = Color.Green
        else textFill = Color.Red
        text = newChange
      }
    }
  }
}

这是不可靠的,您必须通过实施 javafx.scene.control.TableCell 和覆盖传递 empty 标志的方法 updateItem 来实施 cellFactory JavaFX 方式:

cellFactory = {_ =>
  new javafx.scene.control.TableCell[Quote, String] {
    override def updateItem(item: String, empty: Boolean): Unit = {
      super.updateItem(item, empty) 
      if (item == null || empty) {
         text = null
         graphic = null
      }
      else {
        ...
      }
    }
  }
}