使用setData方法将Scala列表转换为JavaFX ObservablesList

问题描述 投票:0回答:1

我正在使用JavaFX。

我在Scala列表中有一个观测列表,类型为List [(Int,Int)]。

我想以某种方式将此列表转换为JavaFX setData方法可以使用的列表:

import javafx.application.Application
import javafx.scene.Scene
import javafx.scene.chart.LineChart
import javafx.scene.chart.NumberAxis
import javafx.scene.chart.XYChart
import javafx.scene.layout.VBox
import javafx.stage.Stage
import javafx.collections.FXCollections
import javafx.collections.ObservableList;

// in a main class somewhere:


val series1: XYChart.Series[Number, Number] = new XYChart.Series()
series1.setName("Portfolio 1")

// this is the list of my values
val list: List[XYChart.Data[Int, Int]] = List();

// I want to convert this to an observable list that I can pass into setData
val observableList: ObservableList[XYChart.Data[Number, Number]] = FXCollections.observableArrayList(list)

series1.setData(observableList)

这将按预期引发类型错误:

found   : List[javafx.scene.chart.XYChart.Data[Int,Int]]
[error]  required: javafx.scene.chart.XYChart.Data[Number,Number]

所以我的问题是,有什么方法可以做我想做的事情。我知道有一个getData方法,但我真的很想弄清楚如何使用setData。

谢谢!

java scala javafx jvm javafx-8
1个回答
0
投票

TL / DR

此作品:

import javafx.collections.{FXCollections, ObservableList}
import javafx.scene.chart.XYChart
import scala.jdk.CollectionConverters._

def convert[A <:B, B ](in: XYChart.Data[A,A]): XYChart.Data[B,B] =
  in.asInstanceOf[XYChart.Data[B, B]]

val series1: XYChart.Series[Number, Number] = new XYChart.Series()
series1.setName("Portfolio 1")

val list:  List[XYChart.Data[Integer, Integer]] = List()
// list: List[javafx.scene.chart.XYChart.Data[Integer,Integer]] = List()

val convertedList = list.map( convert[ Integer, Number ] ).asJava
//convertedList: java.util.List[javafx.scene.chart.XYChart.Data[Number,Number]] = []

val observableList: ObservableList[XYChart.Data[Number, Number]] =
  FXCollections.observableArrayList( convertedList )
//observableList: javafx.collections.ObservableList[javafx.scene.chart.XYChart.Data[Number,Number]] = []

series1.setData( observableList )
series1
//res2: javafx.scene.chart.XYChart.Series[Number,Number] = Series[Portfolio 1]

故障

为了完成这项工作,我们需要一种方法,将您要添加的列表从List[XYChart.Data[ Int, Int ] ]转换为List[ XYChart.Data[ Number, Number ] ],如下所示:

import scala.jdk.CollectionConverters._

val convertedList = list.map( convert[ Int, Number ] ).asJava
val observableList: ObservableList[ XYChart.Data[ Number, Number ] ] =
  FXCollections.observableArrayList( convertedList )

def convert[A, B]( in: XYChart.Data[A,A]): XYChart.Data[B,B] = ???

Upcasting

Java的XYChart.Data< Integer, Integer >被自动转换为XYChart.Data[ Int, Int ]。尽管java.lang.Integer可能是java.lang.Number的子类,但scala.Int不是。为了使它成为一个,我们需要将每个Int还原为Integer

即使如此,将X[ Integer ]添加到X[ Number ]是协变的,而XYChart.Data< X, Y >是不变的。不幸的是,深入研究数据类将无济于事。我们无法覆盖(最终),它没有副本构造函数,仅提取其值就打破了fx基于属性的方法的思想。因此,我们有点卡住了。但是,只要我们继续将其用作属性链,在这里铸造是相对安全的:

def convert[A <:B, B ](in: XYChart.Data[A,A]): XYChart.Data[B,B] =
  in.asInstanceOf[XYChart.Data[B, B]]
© www.soinside.com 2019 - 2024. All rights reserved.