Как я могу изменить изображения JavaFx последовательно, а не все сразу? - PullRequest
0 голосов
/ 28 ноября 2018

Я создаю программу для проверки связи с несколькими компьютерными лабораториями одновременно.На домашнем интерфейсе есть изображения красного или зеленого цвета, в зависимости от того, все компьютеры проверены или нет.Когда я вызываю метод pingAllLabs, он меняет их на красный или зеленый правильно, но все сразу в конце, а не после завершения каждого.

Этот ответ stackOverflow очень похож, но я могуне знаю, как это реализовать

Вот код, который выполняет пинг.В классе Lab он создает массив строк с именами ПК, которые разбиты.

@FXML
public void pingAllLabs() throws IOException{
    for (int  i = 0;i<list.listOfLabs.size();i++{
       list.listOfLabs.get(i).printBroke(fileName);
       updateImages(list.listOfLabs.get(i),i);
    }
}

А вот код, который фактически изменяет изображения.Он извлекает arrayList из поврежденных компьютеров из лаборатории, которую ему отправляют, и, если список не пуст, он меняет изображение в массиве изображений на красный или, если список пуст, он меняет его на зеленый.

    @FXML
public void updateImages(Lab lab,int i){

    Image red = new Image("RedComp.png");
    Image green = new Image("GreenComp.png");

    ArrayList<String> list = lab.getBrokenList();

    if (!list.isEmpty()){
        images.get(i).setImage(red);
        System.out.println("Setting "+lab.getName()+" to red");
    }
    else{
        System.out.println("Setting to green");
        images.get(i).setImage(green);

    }

}

1 Ответ

0 голосов
/ 28 ноября 2018

Для этого метода здесь блок

public void pingAllLabs() throws IOException{
    for (int  i = 0;i<list.listOfLabs.size();i++{
       list.listOfLabs.get(i).printBroke(fileName);
       updateImages(list.listOfLabs.get(i),i);
    }
}

Внести следующие изменения

public void pingAllLabs() throws IOException{

    new Thread(() -> {
           for (int  i = 0;i<list.listOfLabs.size();i++) {
           list.listOfLabs.get(i).printBroke(fileName);
           updateImages(list.listOfLabs.get(i),i);
           }
       }).start();

    }
}

И изменить этот блок

 if (!list.isEmpty()){
        images.get(i).setImage(red);
        System.out.println("Setting "+lab.getName()+" to red");
    }
    else{
        System.out.println("Setting to green");
        images.get(i).setImage(green);

    }

внести следующие изменения

 if (!list.isEmpty()){
        Platform.runLater( () -> images.get(i).setImage(red))
        System.out.println("Setting "+lab.getName()+" to red");
    }
    else{
        System.out.println("Setting to green");
         Platform.runLater( () -> images.get(i).setImage(green))

    }

Так что теперь вы не будете блокировать поток пользовательского интерфейса, а также позволите выполнять обновления асинхронно.

Insights

Проблема сродни вопросу, который вы связали, вы запускаете цикл for в потоке приложения JavaFx, что приводит к тому, что изменения модели не отображаютсянемедленно, но только после того, как вы вернетесь из pingAllLab(), который возвращается только после updateImages(), который содержит цикл.Приведенный выше код запускает логику добавления изображения в другом потоке, а затем отправляет обновления в очередь событий пользовательского интерфейса, используя Platform.runLater().

Следовательно, всякий раз, когда вы пишете код, который каким-либо образом влияет на пользовательский интерфейс, используйте Platform.runLater()

...