Обновление GUI дает эффект мерцания - PullRequest
2 голосов
/ 22 ноября 2011

В настоящее время у меня есть JFrame, где на его панели содержимого я рисую изображения из игрового цикла со скоростью 60 кадров в секунду. Это работает нормально, но с правой стороны у меня теперь есть больше элементов Swing, на которых я хочу отображать некоторую информацию при выборе определенных частей панели содержимого. Эта часть является статическим графическим интерфейсом и не использует игровой цикл.

Я обновляю это так:

public class InfoPanel extends JPanel implements Runnable {
    private String titelType = "type: ";
    private String type;
    private JLabel typeLabel;
    private ImageIcon icon;

    public void update() {
        if (this.icon != null)
            this.typeLabel.setIcon(this.icon);

        if(this.type != null || this.type != "")
            this.typeLabel.setText(this.titelType + this.type);
        else
            this.typeLabel.setText("");
    }

    public void run() {
        try {
            Thread.sleep(150);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        this.update();
    }

(этот метод вызывается только тогда, когда игрок действительно перемещается, поэтому он вызывается только один раз - не 60 раз в секунду)

Я заметил, что при вызове этого update () - метода из игрового цикла я получаю мерцающие эффекты. Я предполагаю, что это потому, что обновление пользовательского интерфейса занимает некоторое время, поэтому я решил поместить его в новый поток. Это уменьшило мерцание, но не помогло.

Далее я решил дать новому потоку низкий приоритет, так как часть экрана, которая перерисовывается 60 раз в секунду, гораздо важнее. Это снова уменьшило мерцание, но это все же произошло. Затем я решил использовать Thread.sleep(150); в новом потоке перед вызовом метода update (), который полностью разрешил эффект мерцания в моей системе.

Однако при запуске его в других системах это все же происходит. Не так часто, как раньше (возможно, один раз в 20 секунд), но это все еще довольно раздражает. Очевидно, что просто обновление пользовательского интерфейса в другом потоке не решит проблему.

Есть идеи, как полностью искоренить мерцание?

Ответы [ 2 ]

4 голосов
/ 22 ноября 2011

Вызовите update() in SwingUtilities.invokeAndWait(), который останавливает поток и обновляет пользовательский интерфейс в EDT.

3 голосов
/ 22 ноября 2011

Проблема в том, что вы используете Thread.sleep(int), который останавливает и останавливает GUI во время EventDispatchTread больше в Concurency в Swing , пример демонстрирует заморозку GUI с помощью Thread.sleep(int), пример для Runnable # Thread

Если вы хотите отложить что-либо в Swing, тогда лучший способ - реализовать javax.swing.Timer

...