[英]How do Iaunch a ScalaFX application from Scala?
我正在嘗試使用以下代碼從http://www.scalafx.org啟動ScalaFX Hello World應用程序:
package car.cadr
object ApplicationStarter {
def main(args: Array[String]) =
javafx.application.Application.launch(classOf[HelloStageDemo], args: _*)
}
為了澄清,我在car.cadr
包中有兩個Scala文件: ApplicationStarter.scala
和HelloStageDemo.scala
。 HelloStageDemo.scala
啟動並運行完全正常,但編譯器抱怨not found: type HelloStageDemo
在ApplicationStarter.scala
上not found: type HelloStageDemo
。 即使我用import car.cadr.HelloStageDemo
手動導入它,編譯器仍然會抱怨。
我正在使用Scala 2.11.1和ScalaFx 8.0.20-R6。
你有幾個問題。
讓我們從編譯器告訴你的那個開始: not found: type HelloStageDemo
。 這是有道理的,因為HelloStageDemo示例定義了一個object
而不是一個類:因此scalac編譯器實際上輸出了一個名為HelloStageDemo$
的類(因為您還可以定義一個class HelloStageDemo
,並且兩者都需要使用不同的名稱進行編譯)。
接下來,如果為class HelloStageDemo
更改object HelloStageDemo
class HelloStageDemo
,則會出現以下錯誤:
Error:(7, 36) overloaded method value launch with alternatives:
(x$1: String*)Unit <and>
(x$1: Class[_ <: javafx.application.Application],x$2: String*)Unit
cannot be applied to (Class[car.cadr.HelloStageDemo], String)
這是因為launch
方法僅存在以下簽名(此處為Java):
public static void launch(Class<? extends javafx.application.Application> appClass, String... args)
public static void launch(String... args)
但HelloStageDemo
既不是String
也不是javafx.application.Application
,所以這不行。
這是因為ScalaFX的JFXApp
特性的工作方式。 這是以常規方式啟動ScalaFX應用程序時執行的主要方法(即,主類是擴展JFXApp
):
import javafx.{application => jfxa}
trait JFXApp extends DelayedInit {
// ...code removed for clarity...
def main(args: Array[String]) {
JFXApp.ACTIVE_APP = this
arguments = args
// Put any further non-essential initialization here.
/* Launch the JFX application.
*/
jfxa.Application.launch(classOf[AppHelper], args: _*)
}
// ...code removed for clarity...
}
因此,在ScalaFX中,擴展javafx.application.Application
的類不是您實現的類,而是AppHelper
提供的AppHelper
類。 請注意,main方法首先在JFXApp
的伴隨對象上設置ACTIVE_APP
屬性:實際上, AppHelper
將執行的操作是啟動JFXApp.ACTIVE_APP
。 這是代碼:
package scalafx.application
private[application] class AppHelper extends javafx.application.Application {
def start(stage: javafx.stage.Stage) {
JFXApp.STAGE = stage
JFXApp.ACTIVE_APP.init()
if (JFXApp.AUTO_SHOW) {
JFXApp.STAGE.show()
}
}
override def stop() {
JFXApp.ACTIVE_APP.stopApp()
}
}
總之,如果你想啟動HelloStageDemo
但是由於某種原因,你不希望HelloStageDemo
成為主類,最簡單的解決方案就是調用main方法 - 畢竟,它只是一個像其他方法一樣的方法:
package car.cadr
object ApplicationStarter {
def main(args: Array[String]) =
HelloStageDemo.main(Array())
}
但是,如果出於某種原因,您絕對必須通過javafx.application.Application.launch
方法啟動ScalaFX應用程序,我認為最好的解決方案是根據自己的喜好重新實現AppHelper
類,這似乎應該是很簡單。
這是一個用於啟動ScalaFX應用程序的簡單模板。
object MyApp {
def main(args: Array[String]) {
MyApp.launch(classOf[MyApp], args: _*)
}
}
class MyApp extends JFXApp {
override def start(primaryStage: Stage): Unit = {
// initialization here
}
}
非ScalaFX解決方案:
我知道這個問題已經回答了。 但是如果你想使用javafx.application.Application來啟動。 只需為類和對象設置不同的名稱,結果是沒有“MyClass $ .class”和“MyClass.class”,其中第二個不是Applications Child而是對象。
以一種巧妙的方式解決了我的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.