Как удержать Java Frame от ожидания? - PullRequest
2 голосов
/ 02 мая 2010

Я пишу генетический алгоритм, который приближает изображение с многоугольником. Проходя через разные поколения, я хотел бы вывести прогресс в JFrame. Тем не менее, похоже, что JFrame ожидает, пока цикл GA завершит работу, чтобы что-то отобразить. Я не верю, что это такая проблема, как перерисовка, так как она в конечном итоге отображает все сразу после завершения цикла while. Я хочу, чтобы графический интерфейс обновлялся динамически, даже когда цикл while работает.

Вот мой код:

while (some conditions) {
    //do some other stuff
    gui.displayPolygon(best);
    gui.displayFitness(fitness);
    gui.setVisible(true);
}

public void displayPolygon(Polygon poly) {
    BufferedImage bpoly = ImageProcessor.createImageFromPoly(poly);
    ImageProcessor.displayImage(bpoly, polyPanel);
    this.setVisible(true);
}

public static void displayImage(BufferedImage bimg, JPanel panel) {
    panel.removeAll();
    panel.setBounds(0, 0, bimg.getWidth(), bimg.getHeight());
    JImagePanel innerPanel = new JImagePanel(bimg, 25, 25);
    panel.add(innerPanel);
    innerPanel.setLocation(25, 25);
    innerPanel.setVisible(true);
    panel.setVisible(true);
}

Ответы [ 2 ]

3 голосов
/ 02 мая 2010

Тем не менее, похоже, что JFrame ждет пока цикл GA заканчивает что-то отображать. Я не считаю, что это проблема перекрасить

Да, если код цикла выполняется в EDT, графический интерфейс не может перерисоваться, пока цикл не завершится. Код цикла должен выполняться в своем собственном потоке, чтобы он не блокировал EDT.

Для получения дополнительной информации прочитайте раздел из учебника по Swing на Параллелизм .

1 голос
/ 02 мая 2010

Я думаю, что ваша проблема в том, что Java не позволит вам обновлять графический интерфейс из другого потока, кроме самого потока графического интерфейса. В какой-то момент это вызывает у всех горе, но, к счастью, найдется достаточно удобный обходной путь.

Идея состоит в том, чтобы передать код, который выполняет обновление как Runnable, методу SwingUtilities.invokeAndWait или SwingUtilities.invokeLater. Вот пример .

Чтобы ваша ГА работала на максимальной скорости и использовала параллелизм, я думаю, invokeLater подойдет.


РЕДАКТИРОВАТЬ: Ой, подождите, решение Camickr намекает, что вы делаете что-то еще: вы запускаете GA в потоке GUI. Ну, это может сделать только один или другой, рассчитать или отобразить. Таким образом, истинное решение объединит оба изменения:

  1. Запустите GA в отдельном потоке (вы можете запустить его в потоке, используемом main() после создания GUI); и
  2. Используйте invokeLater для передачи обновлений в поток GUI (который camickr вызывает EDT, или поток диспетчеризации событий).
...