Анимация с использованием значка Swing, нумерованных изображений .jpg и цикла for в Java - PullRequest
0 голосов
/ 07 апреля 2011
for(int i = 1; i < 65; i++){
diceLbl.setIcon(new  javax.swing.ImageIcon(getClass().getResource("/uhmonopoly/dice/2dice/2dice" + i + ".jpg")));
    diceLbl.repaint();
    repaint();
    diceLbl.revalidate();
    System.out.println(diceLbl.getIcon().toString());

    waiting(100);
    }

public static void waiting (int n){

    long t0, t1;

    t0 =  System.currentTimeMillis();

    do{
        t1 = System.currentTimeMillis();
    }
    while (t1 - t0 < n);
}

Приведенный выше код меняет значок метки с 1 на 65, для анимации броска костей он работает и выводит результат в окне терминала из System.out.println.медленно, но по какой-то причине изображение в графическом интерфейсе не меняется.

Ответы [ 2 ]

4 голосов
/ 07 апреля 2011

Никогда не следует использовать Thread.sleep () или wait () (узкий цикл) в потоке диспетчеризации событий. Это препятствует перерисовке графического интерфейса iself.

Для анимации необходимо использовать таймер Swing.

Прочитайте Swing Tutorial . В разделах «Параллелизм» и «Как использовать таймеры» есть разделы, которые более подробно объясняют вышесказанное.

2 голосов
/ 07 апреля 2011

Здесь происходит одно из двух (и, возможно, оба):

  1. В Swing все действия, относящиеся к графическому интерфейсу, выполняются в одном потоке (потоке диспетчеризации событий, или EDT). Я не могу быть уверен из кода, который вы показали, но я подозреваю, что код, которым вы делитесь, выполняется на EDT. Когда вы вызываете repaint и revalidate, Swing не делает ни одну из этих вещей сразу, а скорее планирует их выполнение при следующей доступной возможности в EDT. Поскольку ваш код выполняется в том же потоке, на котором запланировано перерисовывание, перерисовка не может произойти до тех пор, пока ваш код не завершится (не важно, сколько времени вы ждете).

  2. Ваш метод ожидания выполняет что-то под названием busy-wait . По сути, поскольку вы постоянно проверяете состояние цикла, чтобы увидеть, прошло ли достаточно времени, другие потоки могут не получить возможности для выполнения (или они будут выполняться неэффективно).

Стандартным решением для рисования анимации, подобным этой, является использование таймера для планирования изменений изображения. Вы можете узнать о таймерах в Swing здесь: http://download.oracle.com/javase/tutorial/uiswing/misc/timer.html

Я также рекомендую вам прочитать о параллелизме в Swing здесь: http://download.oracle.com/javase/tutorial/uiswing/concurrency/.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...