Конструктор базового класса не вызывается в JFXApp

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 ("Начало...

Конструктор класса AppFx не запускается, включая println ("этап создания"). Метод openEFO может быть вызван, но переменная stage имеет значение null.

Изменить это упрощение. В DEVAppFx и AppFx будет намного больше функциональности, поэтому важно иметь возможность разделять их функциональность.

2 ответа

Решение

Я думаю, что проблема здесь в том, что scalafx.application.JXFApp это класс, который расширяет scala.DelayedInit черта характера. Таким образом, некоторая магия Scala происходит под капотом: см. Документацию scala.DelayedInit для получения дополнительной информации. К несчастью, DelayedInit глючит и играет хаос с кодом инициализации / построения подкласса - таким как ваш AppFx класс не выполняет свой конструктор.

Боюсь, нет простого решения. До DelayedInit поведение решено, или пока мы не найдем лучший способ инициализации ScalaFXЛучше всего объединить DevAppFx а также AppFx в единый объект, который должен работать как ожидалось.

Например:

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 для этой проблемы.

Итак, в вашем примере строительный код для объекта DevAppFx заменял строительный код для вашего класса AppFxвместо того, чтобы хранить оба, приводя к симптомам, которые вы наблюдали.

Я сделал патч для default а также SFX-8 ветки ScalaFX на Google Code, которые вы можете свободно использовать. В качестве альтернативы, если вы готовы подождать несколько недель, следующие обновления, опубликованные для Sonatype OSS с патчем, будут 1.0.0-R9 (для эквивалента JavaFX 2) и 8.0.0-R5 (для JavaFX 8). эквивалент).

Этот патч должен позволить вашему исходному коду работать без изменений. Если у вас есть шанс попробовать, дайте мне знать, как вы поживаете...

Я использую информацию о возможных ошибках в 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)   
}
Другие вопросы по тегам