我有以下代码
@sfxml
class Charts(private val predicate_chart:ComboBox[String],
private val measure_chart : ComboBox[String],
private val chart_chart : ComboBox[String],
private val chart_graph : ComboBox[String],
private val chart_container:Pane) {
val stackPane = new StackPane()
def createCharts(): Unit ={
new KPie(this).createPie()
}
}
class KPie(charts:Charts) {
def createPieUI(result : ResultSet): Unit ={
val qs: List[QuerySolution] = new IteratorResultSetQuerySolution(result).toList
val pieChartData = ObservableBuffer(qs.map { v: QuerySolution => PieChart.Data(v.get("s").toString, v.getLiteral("measure").getDouble) })
val chart = new PieChart(pieChartData)
charts.stackPane.getChildren.addAll(chart)
}
}
在尝试此操作时,出现以下错误
Error: value stackPane is not a member of Charts
charts.stackPane.getChildren.addAll(chart)
我只想在另一个类中使用控制器类变量。请先帮助我访问那些成员变量。
答案 0 :(得分:1)
我无法测试这是否可以解决您的问题,但是 ScalaFXML documentation表示@sfxml
宏将控制器类替换为生成的版本,该版本有效地删除用户提供的类成员。看来这是您遇到的问题的解释。
文档介绍了一种通过将其他成员放置在扩展了控制器类的trait
(或者可能是abstract class
)中来提供其他类成员的方法。要访问这些成员,您首先需要通过在getController[Trait]
实例上调用Trait
(其中FXMLLoader
是特征的名称)来获得对控制器的引用。按照这种方法,您的代码将如下所示:
trait ChartsMembers {
// Note: This stack pane is not apparently used anywhere.
val stackPane = new StackPane()
// Note: I added the ResultSet argument which is needed for your example.
def createCharts(result: ResultSet): Unit = {
// Note: There was no createPie() member of KPie in your example. I'm assuming that the
// createPieUI(ResultSet) function was the original intended call. Here's what I did:
// 1. Renamed createPie to createPieUI.
// 2. Added the ChartsMembers reference, so that this trait's members are available.
//
// Note: The reference to the KPie instance was neither stored nor returned, and so would
// be garbage collected. Since its charts argument is now redundant, I changed KPie to
// be an object.
KPie.createPieUI(this, result)
}
}
// Note: Charts now extends ChartsMembers.
//
// Note: I have removed the "private val" declarations for the arguments, since they are
// redundant.
@sfxml
class Charts(
predicate_chart: ComboBox[String],
measure_chart: ComboBox[String],
chart_chart: ComboBox[String],
chart_graph: ComboBox[String],
chart_container: Pane
) extends ChartsMembers
// Note: This is now an object - see note above.
object KPie {
// Note: Changed signature - see note above.
def createPieUI(controller: ChartsMembers, result: ResultSet): Unit = {
val qs: List[QuerySolution] = new IteratorResultSetQuerySolution(result).toList
val pieChartData = ObservableBuffer(qs.map { v: QuerySolution =>
PieChart.Data(v.get("s").toString, v.getLiteral("measure").getDouble)
})
val chart = new PieChart(pieChartData)
// Access the stackPane member on the controller.
controller.stackPane.getChildren.addAll(chart)
}
}
要使用以上代码,您首先需要获取一个加载器引用(无论如何都需要),然后使用该引用来调用createCharts
函数:
val result = // As required...
val loader = new FXMLLoader(/*Args as required...*/)
val controller = loader.getReference[ChartsMembers]
// Create the charts on the controller.
controller.createCharts(result)
说实话,这一切似乎都令人费解,并且填充的堆栈窗格没有被任何东西使用或未添加到场景图中,因此上述内容毫无意义。但是,希望您能看到这种方法的工作原理,以便可以在应用程序中实现它。
minimal, complete and verifiable example(包括所有源文件和构建文件)将极大地帮助您。