Controls ScalaFX:是否可以在应用程序对象以外的对象中定义控件?

Controls ScalaFX:是否可以在应用程序对象以外的对象中定义控件?,controls,scalafx,Controls,Scalafx,我试图实现的是:拥有一个ScalaFX应用程序,其中包含一些有序的对象s,称为按钮,标签,复选框等等,以保持一切有序 这里有一个小例子来说明我的意思: 包按钮和标签 导入scalafx.Includes_ 导入scalafx.application.JFXApp 导入scalafx.scene.scene 导入scalafx.scene.control.{按钮,标签} 导入scalafx.event.ActionEvent 对象Main扩展了JFXApp{ stage=新的JFXApp.Pri

我试图实现的是:拥有一个ScalaFX应用程序,其中包含一些有序的
对象
s,称为
按钮
标签
复选框
等等,以保持一切有序

这里有一个小例子来说明我的意思:

包按钮和标签
导入scalafx.Includes_
导入scalafx.application.JFXApp
导入scalafx.scene.scene
导入scalafx.scene.control.{按钮,标签}
导入scalafx.event.ActionEvent
对象Main扩展了JFXApp{
stage=新的JFXApp.PrimaryStage{
title=“测试程序”
场景=新场景(300200){
val label=新标签(“尚未发生任何事情”){
布局X=20
布局Y=20
}
val button1=新按钮(“按钮1”){
布局X=20
布局Y=50
onAction=(e:ActionEvent)=>{
label.text=“B1 klicked”
}
}
val按钮2=新按钮(“按钮2”){
布局X=20
布局Y=80
onAction=(e:ActionEvent)=>{
label.text=“B2 klicked”
}
}
内容=列表(标签、按钮1、按钮2)
}
}
}
此代码显示一个带有标签和两个按钮的窗口,这些按钮更改标签的文本

那很好

但是当我的代码增加了很多控件时,事情就变得一团糟了

这就是为什么我试图将控件转移到其他
对象中(在不同的文件中)。我已将标签放入名为
标签
的对象中:

包按钮和标签
导入scalafx.scene.control.Label
导入scalafx.event.ActionEvent
对象标签{
val label=新标签(“尚未发生任何事情”){
布局X=20
布局Y=20
}
}
当我将其导入主文件时

import Labels.label
一切正常

但我尝试将按钮放入
按钮
对象:

包按钮和标签
导入scalafx.scene.control.Button
导入scalafx.event.ActionEvent
导入标签
对象按钮{
val button1=新按钮(“按钮1”){
布局X=20
布局Y=50
onAction=(e:ActionEvent)=>{
label.text=“B1 klicked”
}
}
val按钮2=新按钮(“按钮2”){
布局X=20
布局Y=80
onAction=(e:ActionEvent)=>{
label.text=“B2 klicked”
}
}
}
这会在我尝试编译时显示错误消息:

找到了[error]:scalafx.event.ActionEvent=>Unit [错误]必需:javafx.event.EventHandler[javafx.event.ActionEvent] [错误]onAction=(e:ActionEvent)=>{
现在我被卡住了,因为我不懂Java

有人知道我想做的事是否可能吗

到目前为止,我还没有在网上找到任何关于这方面的信息。这个问题并没有阻止我编写我想要的程序,但我编写的最后一个应用程序是一个真正的混乱,所有的控件都在一个文件中

我是不是忽略了一些显而易见的东西


任何帮助都将不胜感激。

首先,您的方法完全可以

您看到的错误实际上与Java无关,它是由Scala编译器输出的!它所说的只是提供了一种类型的元素(在本例中,是一个函数,它接受
scalafx.event.ActionEvent
并返回
Unit
),而它需要另一种类型的元素(本例中为
javafx.event.EventHandler[javafx.event.ActionEvent]
instance)

ScalaFX只是JavaFX库的一组Scala友好包装器;如果没有在两组元素之间转换的
隐式
转换函数,Scala编译器会抱怨在需要JavaFX元素时查找ScalaFX元素,反之亦然

解决方案是确保将以下
import
添加到每个ScalaFX源文件中:

导入scalafx.Includes_
(此文件位于主源文件的顶部,而不是其他文件。)

这将确保您的ScalaFX
ActionEvent
处理程序被转换为JavaFX等效程序,从而使您的生活更加轻松

这是ScalaFX中非常常见的一种错误类型,几乎总是通过指定上面的
导入
来修复(如果
导入
无法解决问题,那么您通常会遇到真正的类型混淆,您只是简单地使用了错误类型的对象。)

因此,我认为您的代码应该是这样的:

Main.scala

导入scalafx.Includes_
导入scalafx.application.JFXApp
导入scalafx.scene.scene
导入按钮和标签_
对象Main扩展了JFXApp{
stage=新的JFXApp.PrimaryStage{
title=“测试程序”
场景=新场景(300200){
内容=列表(Labels.label,Buttons.button1,Buttons.button2)
}
}
}
按钮标签/Labels.scala

包按钮和标签
导入scalafx.Includes_
导入scalafx.scene.control.Label
对象标签{
val label=新标签(“尚未发生任何事情”){
布局X=20
布局Y=20
}
}
按钮标签/Buttons.scala

包按钮和标签
导入scalafx.Includes_
导入scalafx.scene.control.Button
导入scalafx.event.ActionEvent
导入标签
对象按钮{
val button1=新按钮(“按钮1”){
布局X=20
布局Y=50
onAction=(e:ActionEvent)=>{
label.text=“B1 klicked”
}
}
val按钮2=新按钮(“按钮2”){
布局X=20
布局Y=80
onAction=(e:ActionEvent)=>{
label.text=“B2 klicked”
}
}
}
(注意,按照惯例,包名称通常都是小写的。)

您需要注意的一件事是JavaFX应用程序线程:与wi进行交互的所有代码