Hello! I decided to write a toy on java, implemented graphics using api-java fx (the point is that there are a number of countries in the game, a stream is allocated for each country, and they try to destroy each other using special methods, while the game is divided into moves, and for 1 move each country can only be like 1 time, the game ends when 1 country remains - it is considered the winner). I wrote the logic, I try to add it to the chart, so that it dynamically changes as the program runs (the results of battles were displayed on the game console, the countries on the game map were repainted in the colors of the winners, etc.), but this is where the problem arose - when you start the game, she thinks for some time (about 2-3 seconds) and immediately gives the result of all the moves in the game window, as well as the card already completely painted over in the winner's color. And you need to change the game window dynamically, in the course of the program. I tried many things, but did not find the result, I can’t even fully understand what the error is, I attach the code:

import javafx.application.Platform; import javafx.concurrent.Task; import javafx.fxml.FXML; import javafx.scene.control.TextArea; import javafx.scene.effect.ColorAdjust; import javafx.scene.image.ImageView; import java.util.ArrayList; import java.util.concurrent.Phaser; public class MultiMain { @FXML TextArea display; @FXML ImageView Portugal; @FXML ImageView Spain; @FXML ImageView France; @FXML ImageView Germany; @FXML ImageView Switzeland; @FXML ImageView Italy; Phaser phaser; CommonResource res; int phase; @FXML public void initialize() { setColorPortugal(0.1); // изменение цветового диапазона карт в игре setColorSpain(0.2); setColorFrance(0.3); setColorGermany(0.4); setColorSwitzeland(0.5); setColorItaly(0.6); } public void setDisplay(String msg) { display.setText(display.getText() + "\n" + msg); } public void setColorItaly(Double hue) { ColorAdjust colorAdjust = new ColorAdjust(); colorAdjust.setHue(hue); Italy.setEffect(colorAdjust); } public void setColorSpain(Double hue) { ColorAdjust colorAdjust = new ColorAdjust(); colorAdjust.setHue(hue); Spain.setEffect(colorAdjust); } public void setColorPortugal(Double hue) { ColorAdjust colorAdjust = new ColorAdjust(); colorAdjust.setHue(hue); Portugal.setEffect(colorAdjust); } public void setColorFrance(Double hue) { ColorAdjust colorAdjust = new ColorAdjust(); colorAdjust.setHue(hue); France.setEffect(colorAdjust); } public void setColorSwitzeland(Double hue) { ColorAdjust colorAdjust = new ColorAdjust(); colorAdjust.setHue(hue); Switzeland.setEffect(colorAdjust); } public void setColorGermany(Double hue) { ColorAdjust colorAdjust = new ColorAdjust(); colorAdjust.setHue(hue); Germany.setEffect(colorAdjust); } public void actionStart() { phaser = new Phaser(1); res = new CommonResource(); int somebodyWon; boolean stop = false; new Thread(new CountryThread(res, "Portugal", new Country("Portugal", 1, 1, 8, 8, 0.1))).start(); //setColorPortugal(0.1); new Thread(new CountryThread(res, "Spain", new Country("Spain", 1, 2, 8, 9, 0.2))).start(); //setColorSpain(0.2); new Thread(new CountryThread(res, "France", new Country("France", 2, 1, 3, 4, 0.3))).start(); //setColorFrance(0.3); new Thread(new CountryThread(res, "Germany", new Country("Germany", 2, 2, 9, 7, 0.4))).start(); //setColorGermany(0.4); new Thread(new CountryThread(res, "Switzeland", new Country("Switzeland", 1, 3, 3, 4, 0.5))).start(); //setColorSwitzeland(0.5); new Thread(new CountryThread(res, "Italy", new Country("Italy", 2, 3, 5, 6, 0.6))).start(); //setColorItaly(0.6); while (!stop) { somebodyWon = res.names.size(); if (somebodyWon != 1) { // ждем завершения фазы phase = phaser.getPhase(); phaser.arriveAndAwaitAdvance(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Ход " + phase + " завершен"); System.out.println("Выжили: " + res.printWhoAlive()); System.out.println(" "); setDisplay("Ход " + phase + " завершен"); // вывод на дисплей игры setDisplay("Выжили: " + res.printWhoAlive()); } else { phaser.arriveAndDeregister(); // сообщаем о завершении фаз и удаляем с регистрации объекты stop = true; //return; } } } class CountryThread extends Task { String name; CommonResource res; Country country; CountryThread(CommonResource res, String n, Country country) { this.name = n; this.res = res; this.country = country; phaser.register(); } public void runSmth() { /*Platform.runLater(new Runnable() { @Override public void run() {*/ int somebodyWon; boolean stop = false; while (!stop) { somebodyWon = res.names.size(); if (somebodyWon != 1) { res.attack(name); phaser.arriveAndAwaitAdvance(); // сообщаем, что первая фаза достигнута } else { phaser.arriveAndDeregister(); // сообщаем о завершении фаз и удаляем с регистрации объекты stop = true; //return; } } /*} });*/ } @Override protected Object call() throws Exception { runSmth(); return 1; } } class CommonResource { ArrayList<Country> names = new ArrayList<>(); CommonResource() { names.add(new Country("Portugal", 1, 1, 8, 8, 0.1)); names.add(new Country("Spain", 1, 2, 8, 9, 0.2)); names.add(new Country("France", 2, 1, 3, 4, 0.3)); names.add(new Country("Germany", 2, 2, 9, 7, 0.4)); names.add(new Country("Switzeland", 1, 3, 3, 4, 0.5)); names.add(new Country("Italy", 2, 3, 5, 6, 0.6)); } public String printWhoAlive() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < names.size(); i++) { sb.append(names.get(i).getName()); sb.append("; "); } return sb.toString(); } synchronized void attack(String name) { // метод атаки (логика) try { String ownName = name; int ownIndex = -1; for (int i = 0; i < names.size(); i++) { if (names.get(i).getName().equals(ownName)) { ownIndex = i; break; } } if (ownIndex != -1) { for (int i = 0; i < names.size(); i++) { if (i != ownIndex) { System.out.println("собственное имя " + names.get(ownIndex).getName() + " просматривает " + names.get(i).getName()); if (names.get(ownIndex).isNeighbor(names.get(i))) { boolean IWon = names.get(ownIndex).Attack(names.get(i)); if (IWon) { for (int j = 0; j < names.get(i).getiOwn().size(); j++) { names.get(ownIndex).setiOwn(names.get(i).getiOwn().get(j)); } names.get(ownIndex).setiOwn(names.get(i).getName()); for (int j = 0; j < names.get(ownIndex).getiOwn().size(); j++) { switch (names.get(ownIndex).getiOwn().get(j)) { case "Portugal": setColorPortugal(names.get(ownIndex).getHue()); break; case "Spain": setColorSpain(names.get(ownIndex).getHue()); break; case "France": setColorFrance(names.get(ownIndex).getHue()); break; case "Germany": setColorGermany(names.get(ownIndex).getHue()); break; case "Switzeland": setColorSwitzeland(names.get(ownIndex).getHue()); break; case "Italy": setColorItaly(names.get(ownIndex).getHue()); break; default: { System.out.println("error while try to chanhe color"); break; } } } names.remove(names.get(i)); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } return; } } } } else { //Thread.currentThread().interrupt(); } } catch (Exception e) { } } } } 

Please tell me what could be the problem.

PS - window view enter image description here

  • I suspect that setColor * methods should be called in fx application thread, you need to wrap in Platform.runLater (() -> setColor *) - Ruslan P.
  • I tried it - everything is the same, repainting the map and outputting the results to the TextArea at the end of the game, does not want to dynamically do it ( - Alex

1 answer 1

In general, I rewrote the program again without using phasera and it all worked.