Jbutton действие, setIcon выполняется в конце действия - PullRequest
2 голосов
/ 12 февраля 2011

Я разрабатываю свою первую игру AWT.Я пытаюсь установить значок для кнопки, когда она нажата (при некоторых условиях).Вот соответствующая часть кода:

if (tileIsMemTile) {
        System.out.println("!!! Right Tile !!!");
        memTile.setBackground(Color.red);
        numberOfMemTilesToGuess -= 1;
        System.out.println("It rest " + numberOfMemTilesToGuess + " tiles to guess");
    } else {
        System.out.println("!!! Wrong Tile !!!");
        Icon falseTileIcon = new ImageIcon(getClass().getResource("wrong.png"));
        memTile.setIcon(falseTileIcon);
        wrongGuessAction();         
    }

    System.out.println(">>> Action processed >>>");

    if (numberOfMemTilesToGuess == 0) {
        System.out.println("\n END OF THE LEVEL");
        System.out.println("Congratulations, you guessed all the tiles without error !! \n");

        dispose();
        //TODO  !!!! SHOW INTERLEVEL INFORMATION !!!!

        if (memGridDimX != maxDimX && memGridDimY != maxDimY) {
            if (memGridDimX == memGridDimY)
                new Memory(memGridDimX, memGridDimY + 1);
            else
                new Memory(memGridDimX + 1, memGridDimY);
        } else
            System.out.println("You have a really good memory my friend!");
    }
}

private void wrongGuessAction() {
    //TODO !!! FAILED IN LEVEL MESSAGE !!!

    try { Thread.sleep(2000); } catch (Exception e1) {}
    dispose();

    if (memGridDimX == initialDimX && ( memGridDimY == initialDimY || memGridDimY == initialDimY + 1))  
        new Memory(initialDimX, initialDimY);
    else
        new Memory(memGridDimX - 1, memGridDimY - 1);
}

Так что здесь, после того, как я установил иконку jbutton, я хочу увидеть ее, прежде чем избавиться от старого jframe и запустить новый (следующий уровень в игре),но несмотря на попытки отложить выполнение функции dispose () с помощью:

try {Thread.sleep (2000);} catch (Exception e1) {}

и с любыми другими функциями задержки (такими как сравнение currenttimemillis (), to-t1), которые я даже пытался использовать;

memTile.setBackground(Color.green);
int i = 0;
do {
System.out.println(i); i++;
} while (!memTile.getIcon().equals(Color.green));

на самом деле последний, кажется, работает, но затмение переходит в режим отладки без каких-либо исключений, и это не останавливает процесс, даже когда я закрываю фрейм.

Так что ничего не работает.В каждом случае рамка закрывается, и я не вижу значок на кнопке.если я оставляю комментарий и оставляю его для создания следующего кадра, старый кадр остается, значок загружается на кнопку, и создается новый кадр.Я не мог понять принцип выполнения метода setIcon.

Заранее спасибо.

// memTile.setBackground (Color.green);// int i = 0;// do {//
// System.out.println (i);я ++;//} while (! memTile.getIcon (). equals (Color.green));

Ответы [ 3 ]

2 голосов
/ 12 февраля 2011

ActionListener вызывается в потоке диспетчеризации событий AWT. Тот же поток обрабатывает и любые другие события, такие как краски. Таким образом, до тех пор, пока ваш метод actionPerformed() не возвращается, ничего не отображается (или что-либо еще в графическом интерфейсе изменяется).

Вы должны выполнять более длительные действия вне этого потока (т. Е. Запускать новый поток, делая это), а затем для изменений GUI позже перезвонить с EventQueue.invokeLater (или EventQueue.invokeAndWait).

1 голос
/ 12 февраля 2011

Мне нужно больше узнать о EventQueue.

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

Может быть, ваш Thread.sleep (...) код должен быть заменен на Swing Timer.В руководстве по Swing также есть раздел «Как использовать Swing Timers».

1 голос
/ 12 февраля 2011

Пагло Эберманн дает правильный ответ, но я просто хочу добавить, что никогда не спит в потоке рассылки событий! Это только усугубляет ситуацию.Swing - это мощный инструментарий, но он допускает некорректную работу с потоками (спящий режим на EDT, обновляет пользовательский интерфейс вне EDT) - это ИМХО причина номер один, почему у людей возникают проблемы с Swing.Если вместо этого произойдет сбой с RuntimeException , то при таких обстоятельствах будет выявлено много ошибок и, следовательно, их будет легче исправить.

...