Конструктор базового класса не вызывается в 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)
}