使用 setData 方法将 Scala 列表转换为 JavaFX ObservablesList
Converting a Scala List to a JavaFX ObservablesList using setData method
我正在使用 JavaFX。
我在 Scala List 中有一个观察列表,类型为 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。
谢谢!
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] = ???
向上转型
Java 的 XYChart.Data< Integer, Integer >
自动转换为 XYChart.Data[ Int, Int ]
。虽然 java.lang.Integer
可能是 java.lang.Number
的子 class,但 scala.Int
不是。为了使它成为一个,我们需要将每个 Int
恢复为 Integer
.
即便如此,在X[ Number ]
上加一个X[ Integer ]
是协变的,而XYChart.Data< X, Y >
是不变的。不幸的是,深入研究 Data-class 无济于事。我们不能覆盖 (final),它没有复制构造函数,并且简单地提取它的值打破了 fx 基于 属性 的方法背后的想法。所以,我们有点卡住了。不过,casting在这里还是比较安全的,只要我们继续把它当作一个属性-chain:
def convert[A <:B, B ](in: XYChart.Data[A,A]): XYChart.Data[B,B] =
in.asInstanceOf[XYChart.Data[B, B]]
我正在使用 JavaFX。
我在 Scala List 中有一个观察列表,类型为 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。
谢谢!
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] = ???
向上转型
Java 的 XYChart.Data< Integer, Integer >
自动转换为 XYChart.Data[ Int, Int ]
。虽然 java.lang.Integer
可能是 java.lang.Number
的子 class,但 scala.Int
不是。为了使它成为一个,我们需要将每个 Int
恢复为 Integer
.
即便如此,在X[ Number ]
上加一个X[ Integer ]
是协变的,而XYChart.Data< X, Y >
是不变的。不幸的是,深入研究 Data-class 无济于事。我们不能覆盖 (final),它没有复制构造函数,并且简单地提取它的值打破了 fx 基于 属性 的方法背后的想法。所以,我们有点卡住了。不过,casting在这里还是比较安全的,只要我们继续把它当作一个属性-chain:
def convert[A <:B, B ](in: XYChart.Data[A,A]): XYChart.Data[B,B] =
in.asInstanceOf[XYChart.Data[B, B]]