3

我正在制作一个带有 ScalaFX GUI 和 Akka 远程网络的多人游戏客户端。当我的客户端收到游戏数据时,它会将其存储在 Model.gameData 中。我需要我的 GUI 来响应这个变量的变化。

我使用 gameData 在我的模型对象中创建 data:ObjectProperty:

object Model  {
    var gameData:Option[GameData] = None
    val data = new ObjectProperty(this,"data",Model.gameData)
    ...
}

drawGrid 和 drawPlayer 是我用来更新 GUI 的方法,位于 CleintGUI 对象中。我厌倦了使用 addListener 和 onChange,它们可以编译,但我放置在其中的方法从未被调用。

object ClientGUI extends JFXApp{
 ...

 Model.data.addListener{ (o: javafx.beans.value.ObservableValue[_ <:Option[GameData]], oldVal: Option[GameData], newVal: Option[GameData]) =>
  drawGrid
  drawPlayer
 }

 Model.data onChange {
  drawGrid
  drawPlayer
 }

}

我错过了什么?我是否在 ClientGUI 中错误地声明了 data:ObectProperty 或方法?

当我通过在 TextField 中提交字符串来创建事件来手动调用它们时,drawGrid 和 drawPlayer 都可以工作。当我收到 GameData 时,我还尝试在我的 actor 类中直接调用 drawGrid 和 drawPlayer 表单,但我收到一个错误“不是 FX 线程”。

编辑:我通过改变控制属性来更新 GUI。但是,理想情况下,我想通过使用条件表达式来定义控件属性:

val data = new BooleanProperty(this,"data",Model.gameData.isDefined)

val msgLabel = new Label{
                 text <== when(data) choose " " otherwise "No GameData"
               } 

但这不起作用,因为我无法找到定义 BooleanProperty 的方法,以便 when(data) 根据布尔 Model.gameData.isDefined 更改值

4

1 回答 1

1

当我收到 gameData 时,我正在使用 GridPane.add 方法向 GUI 添加新元素。

我没有这样做,而是在对象创建期间添加了所有控件(gui 节点/元素),然后在收到 gameData 时更改了它们的相关属性。

例如,当我收到 gameData 时,我将 Label.text 从“No Game Data”设置为空字符串:

def update {
ClientGUI.msgLabel = " "
}

我认为这不是最好的方法,因为现在我在多线程应用程序中拥有公开可用的 var,但是因为我只在收到新数据时从一个地方更改它们,所以应该没问题。

理想情况下,我想通过使用条件表达式来定义控件属性:

val data = new BooleanProperty(this,"data",Model.gameData.isDefined)

val msgLabel = new Label{
                 text <== when(data) choose " " otherwise "No GameData"
               } 

但这不起作用,因为我无法找到定义 BooleanProperty 的方法,以便 when(data) 根据布尔 Model.gameData.isDefined 更改值

于 2015-11-16T13:05:45.160 回答