在JFXApp中未调用基类构造函数

时间:2014-03-18 01:33:23

标签: scala javafx scalafx

package pGrid
package pUIFx
import pUtil._    

object DevAppFx extends AppFx
{
  println("Begining DevFxApp object constructor in package pGrid.pUIFx")   
  //devStart 
}

package pGrid
package pUIFx
import pGeom._
import pGrid.pDev._

import scalafx.application._
import scalafx.application.JFXApp._
import scalafx.scene._
import scalafx.scene.paint._

class AppFx extends JFXApp with DevTr
{   
  println("Creating stage")
  stage =  new PrimaryStage
  {
    x = 3850
    y = 200
    width = 1000
    height = 800          
    scene = new Scene
  }
  def openEFO(de: DescEFlatOne): Unit =
  {
    println("def in AppFx")
    stage.scene = ScrEditFx(stage, de)            
  }
}

运行DevAppFx对象构造函数,包括println(“Beginning ...

类AppFx构造函数不运行,包括println(“创建阶段”)。可以调用openEFO方法,但stage变量为null。

编辑这是一种简化。 DEVAppFx和AppFx中将有更多功能,因此能够将功能分开是很重要的。

2 个答案:

答案 0 :(得分:3)

我认为这里的问题是scalafx.application.JXFApp是一个扩展scala.DelayedInit特征的类。因此,一些 Scala魔法在幕后发生:请参阅scala.DelayedInit文档了解更多信息。遗憾的是,DelayedInit是错误的,并且会对子类初始化/构造代码造成严重破坏 - 例如您的AppFx类没有执行其构造函数。

对此我没有简单的解决办法,我很害怕。在DelayedInit行为得到解决之前,或者在我们找到更好的方法来初始化ScalaFX之前,您最好的办法是将DevAppFxAppFx合并到一个对象中,按预期工作。

例如:

package pGrid
package pUIFx
import pGeom._
import pGrid.pDev._

import scalafx.application._
import scalafx.application.JFXApp._
import scalafx.scene._
import scalafx.scene.paint._

object AppFx extends JFXApp with DevTr
{   
  println("Creating stage")
  stage =  new PrimaryStage
  {
    x = 3850
    y = 200
    width = 1000
    height = 800          
    scene = new Scene
  }
  // Relocate DevAppFx init here...
  println("Begining DevFxApp object constructor in package pGrid.pUIFx")   
  //devStart 
  def openEFO(de: DescEFlatOne): Unit =
  {
    println("def in AppFx")
    stage.scene = ScrEditFx(stage, de)            
  }
}

<强>更新

我做了更多的挖掘,scalafx.application.JFXApp没有很好地实现scala.DelayedInit特征的语义。本质上,它只是将类/对象的构造/初始化代码存储在继承层次结构的底部,并丢弃其他所有代码。有关详细信息,请参阅ScalaFX bug report for this issue

因此,在您的示例中,对象DevAppFx的构造代码正在替换类AppFx的构造代码,而不是存储两者,从而导致您观察到的症状。

我已经为ScalaFX on Google CodedefaultSFX-8分支提供了一个补丁,您可以自由使用。或者,如果您准备等待几周,那么发布到Sonatype OSS以获得补丁的下一个更新将是1.0.0-R9(对于JavaFX 2等效)和8.0.0-R5(对于JavaFX 8等效)。

此补丁应允许您的原始代码未经修改地运行。如果你有机会尝试一下,请告诉我你是如何进行的......

答案 1 :(得分:0)

我从Mike Allen的回答中使用了有关DelayedInit中可能存在的错误的信息。但是,我希望将功能分开,而不是将其组合到一个对象中。阅读文档时,问题在于类和对象没有从JFXApp和DelayedInit继承的特征,因此我将AppFx转换为特征并将舞台创建移动到方法中

object DevAppFx extends AppFx with DevTr
{
  openStage
  devStart 
}

__ _ __ _ __ _ __ _ -

trait AppFx extends JFXApp with StratApp
{
  def openStage: Unit = stage =  new PrimaryStage
  {
    x = 3850
    y = 200
    width = 1000
    height = 800          
    scene = new Scene
  }
  override def openEFO(de: DescEFlatOne): Unit = stage.scene = ScrEditFx(this, de)   
}