I am creating a GUI for a Board Game using javaFX via RMI. I have a lot of problems because after having found a way for update my GUI I cannot really update GUI if I don't place a toggle breakpoint in a certain line.
If I start my clients not in debug mode the graphics don't seem to do the update, they just appear and nothing happens anymore.
Also if I do not place the toggle in a specified line of my code, and I place it in another line (deeper in the method calling sequence)nothing happens. So the client thread doesen't stop; as if it don't does the method call that it does with the breakpoint. I start my clients all in the same machine and only one (using toggle break points) gets updated.
Now I will show you my code.
javafx starts here in a clas called RMIGUIView.java
@Override
public synchronized void run() {
waiting = true;
pause();
guiDisplayer = new GUIDisplayer();
(new Thread(() -> guiDisplayer.startGUI())).start();
waiting = false;
do {
state.acceptView(this);
} while(!endGame);
}
then I do the start of the GUI (during the start method I save the stage on the controller as it is suggested here Passing Parameters JavaFX FXML
public class GUIDisplayer extends Application {
private StartTurnState currentState;
private Stage stage;
public void start(Stage stage) throws Exception {
GUIController controller = new GUIController();
FXMLLoader fxmlLoader = new FXMLLoader();
Parent root = fxmlLoader.load(getClass().getResource("sceneMap.fxml"));
stage.setTitle("Council of Four");
Scene newScene = new Scene(root);
stage.setScene(newScene);
stage.show();
controller.setStage(stage);
}
public static void startGUI() {
Application.launch();
} }
after start of the gui I return in my RMIGUIView.java and I do this
@Override
public void visit(StartTurnState currentState) {
GUIController guiController = new GUIController();
guiController.updateGUI(currentState);
}
and here It is my controller class where I have to put the toggle breakpoint if I want somethig happen (please read at the class comments)
public class GUIController {
@FXML
ArrayList<ImageView> citiesImagesList;
@FXML
Group group;
@FXML
TableView<Player> players;
@FXML
TableColumn<Player, String> playerName;
@FXML
TableColumn<Player, String> victoryPoints;
@FXML
TableColumn<Player, String> coins;
@FXML
TableColumn<Player, String> assistants;
@FXML
TableColumn<Player, String> nobilityPoints;
@FXML
ImageView A;
@FXML
ImageView B;
@FXML
ImageView C;
@FXML
ImageView D;
@FXML
ImageView E;
@FXML
ImageView F;
@FXML
ImageView G;
@FXML
ImageView H;
@FXML
ImageView I;
@FXML
ImageView J;
@FXML
ImageView K;
@FXML
ImageView L;
@FXML
ImageView M;
@FXML
ImageView N;
@FXML
ImageView O;
@FXML
ImageView king;
private static StartTurnState currentState;
private static GUIController self = null;
private static Stage stage;
public GUIController() {
self = this;
}
private void placeRewardToken(Group group, List<ImageView> citiesImagesList) {
Map<String, City> citiesMap = GUIController.currentState.getGameMap().getCitiesMap();
for (ImageView imageView : citiesImagesList) {
City city = citiesMap.get(imageView.getId().toString());
if (city instanceof NormalCity) {
RewardToken rewardToken = ((NormalCity) city).getRewardToken();
Text text = new Text();
text.setText(rewardToken.toString());
text.setX(imageView.getLayoutX() + 5.00);
text.setY(imageView.getLayoutY());
text.toFront();
text.setFont(Font.font("Verdana", 12));
text.setFill(Color.MAGENTA);
group.getChildren().add(text);
}
}
}
private void setPlayerSet() {
Platform.setImplicitExit(false);
Scene scene = stage.getScene();
ObservableList<Player> playersList = FXCollections.observableArrayList();
playersList.addAll(GUIController.currentState.getPlayerSet().getPlayers());
TableView<Player> playerTable = (TableView<Player>) scene.lookup("#players");
TableColumn<Player, String> playersName = ((TableColumn<Player, String>) playerTable.getColumns().get(0));
playersName.setCellValueFactory(new PropertyValueFactory<Player, String>("name"));
TableColumn<Player, String> victoryPoints = ((TableColumn<Player, String>) playerTable.getColumns().get(1));
victoryPoints.setCellValueFactory(new PropertyValueFactory<Player, String>("victoryPoints"));
TableColumn<Player, String> coins = ((TableColumn<Player, String>) playerTable.getColumns().get(2));
coins.setCellValueFactory(new PropertyValueFactory<Player, String>("coins"));
TableColumn<Player, String> assistants = ((TableColumn<Player, String>) playerTable.getColumns().get(3));
assistants.setCellValueFactory(new PropertyValueFactory<Player, String>("assistants"));
TableColumn<Player, String> nobilityPoints = ((TableColumn<Player, String>) playerTable.getColumns().get(4));
nobilityPoints.setCellValueFactory(new PropertyValueFactory<Player, String>("nobilityTrackPoints"));
playerTable.setItems(playersList);
}
private void placeKing(ImageView king, List<ImageView> citiesImagesList) {
for (ImageView imageView : citiesImagesList) {
if (imageView.getId().toString().equals(GUIController.currentState.getKing().getPosition().getName())) {
king.setX(imageView.getLayoutX());
king.setY(imageView.getLayoutY());
}
}
}
@FXML
public void initialize() {
self = this;
}
public void setStage(Stage stage) {
this.stage = stage;
}
public void updateGUI(StartTurnState state) {
GUIController.currentState = state;
updateMap(); //here I should set my toggle breakpoint
}
private void updateMap() {
Scene scene = stage.getScene();
List<ImageView> citiesImagesList = new ArrayList<>();
citiesImagesList.add((ImageView) scene.lookup("#A"));
citiesImagesList.add((ImageView) scene.lookup("#B"));
citiesImagesList.add((ImageView) scene.lookup("#C"));
citiesImagesList.add((ImageView) scene.lookup("#D"));
citiesImagesList.add((ImageView) scene.lookup("#E"));
citiesImagesList.add((ImageView) scene.lookup("#F"));
citiesImagesList.add((ImageView) scene.lookup("#G"));
citiesImagesList.add((ImageView) scene.lookup("#H"));
citiesImagesList.add((ImageView) scene.lookup("#I"));
citiesImagesList.add((ImageView) scene.lookup("#J"));
citiesImagesList.add((ImageView) scene.lookup("#K"));
citiesImagesList.add((ImageView) scene.lookup("#L"));
citiesImagesList.add((ImageView) scene.lookup("#M"));
citiesImagesList.add((ImageView) scene.lookup("#N"));
citiesImagesList.add((ImageView) scene.lookup("#O"));
ImageView king = (ImageView) scene.lookup("#king");
Group group = (Group) scene.lookup("#group");
setPlayerSet(); //if I try setting here my toggle the thread doesent stop as the method updateGui() is never called
placeKing(king, citiesImagesList);
placeRewardToken(group, citiesImagesList);
} }
I hope you understand my question. I will Edit my question if you do not understand something. I have not found something like this here on Stackoverflow.
Thanks in advance for your help.
EDIT: I have tryed to rewrite the code as suggested by James_D this is my new call to the Update to GUI.
@Override
public void visit(StartTurnState currentState) {
guiDisplayer.setState(currentState);
Platform.runLater(()-> guiDisplayer.run());
}
I have also modified the GUIDisplayer Class
public class GUIDisplayer extends Application implements Runnable{
private StartTurnState currentState;
private Stage stage;
static GUIController guiController;
public void start(Stage stage) throws Exception {
GUIController controller = new GUIController();
FXMLLoader fxmlLoader = new FXMLLoader();
Parent root = fxmlLoader.load(getClass().getResource("sceneMap.fxml"));
stage.setTitle("Council of Four");
Scene newScene = new Scene(root);
stage.setScene(newScene);
stage.show();
controller.setStage(stage);
setController(controller);
}
public static void startGUI() {
Application.launch();
}
public void setState(State state) {
currentState = (StartTurnState) state;
}
public static void setController(GUIController controller) {
guiController = controller;
}
@Override
public void run() {
guiController.doUpdateGUI(currentState);
} }
The runLater method call seems to be ignored, maybe I am in this case descibed by the javadoc
If this method is called after the JavaFX runtime has been shutdown, the call will be ignored: the Runnable will not be executed and no exception will be thrown.
if I remove the runLater and add toggle brackpoints I can still modify the GUI.