Reputation: 41
I am making a multiplayer game client with ScalaFX GUI and Akka remoting for networking. When my client receives game data it stores it inside Model.gameData. I need my GUI to respond to this variable change.
I used gameData to create data:ObjectProperty in my Model object:
object Model {
var gameData:Option[GameData] = None
val data = new ObjectProperty(this,"data",Model.gameData)
...
}
drawGrid and drawPlayer are methods I use to update the GUI, located in CleintGUI object. I tired using addListener and onChange, they compile but the methods I placed inside of them are never invoked.
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
}
}
What am I missing? Am I declaring data:ObectProperty or methods inside my ClientGUI incorrectly?
drawGrid and drawPlayer both work when I call them manually by creating an event through submitting a string in a TextField. When I receive GameData I also tried to directly call drawGrid and drawPlayer form inside of my actor class, but I got an error "Not an FX thread".
Edit: I got the GUI to update by mutating control attributes. However, ideally I would want to define the control attributes by using conditional expressions:
val data = new BooleanProperty(this,"data",Model.gameData.isDefined)
val msgLabel = new Label{
text <== when(data) choose " " otherwise "No GameData"
}
But this doesn't work as I can't figure out a way to define BooleanProperty such that when(data) changes value depending on boolean Model.gameData.isDefined
Upvotes: 3
Views: 527
Reputation: 41
I was adding new elements to the GUI when I received gameData, by using GridPane.add method.
Instead of doing that I added all the controls(gui nodes/elements) during object creation and then changed their relevant attributes when I receive gameData.
e.g. I set Label.text from "No Game Data" to an empty string when I receive gameData:
def update {
ClientGUI.msgLabel = " "
}
I don't think this is the best approach as now I have publicly available vars in a multi threaded application, but since I only change them from one place when I receive new data it should be fine.
Ideally I would want to define the control attributes by using conditional expressions:
val data = new BooleanProperty(this,"data",Model.gameData.isDefined)
val msgLabel = new Label{
text <== when(data) choose " " otherwise "No GameData"
}
But this doesn't work as I can't figure out a way to define BooleanProperty such that when(data) changes value depending on boolean Model.gameData.isDefined
Upvotes: 1