Java Swing: Paint (), doLayout () не синхронизированы. Например. Сообщение об ошибке отображается неправильно, при изменении размера окна происходит сбой - PullRequest
1 голос
/ 27 октября 2010

Я работаю над Java-приложением с пользовательским интерфейсом, состоящим из:

  • верхний колонтитул
  • левое меню
  • текст заголовка
  • сообщение об ошибке (отображается в заголовке страницы)
  • центральный контейнер (JPanel), который изменяется динамически, в зависимости от выбранного пункта меню (с левой стороны)

При наличии каких-либо ошибок в вычислениях в заголовке приложения отображается сообщение об ошибке (расположение в заголовке страницы). Сообщения об ошибках могут быть разными: одни состоят из одной строки, а другие длиннее (2,3 строки)

Когда появляется длинная ошибка, она может отображаться правильно или нет (сообщение отображается поверх других компонентов). Насколько я знаю, при изменении компонентов пользовательского интерфейса методы doLayout (), repaint () вызываются независимо, и они должны корректировать компоновку.

Недавно я прочитал о EDT и заметил, что свинг-приложение должно быть организовано в соответствии с принципами EDT.

Я думаю, что это решит мою проблему, потому что все операции будут синхронизированы, и я буду управлять последовательностью вызовов методов.

Но сейчас у меня недостаточно времени для рефакторинга приложения, и это запланировано на следующий выпуск.

Знаете ли вы другое решение, которое поможет в настройке макетов? Эта проблема очень сложная, я не могу ее воспроизвести. Но это появляется время от времени.

Большое спасибо. Серджиу

PS: Если у вас есть какие-либо вопросы или требуются дополнительные сведения, пожалуйста, не стесняйтесь обращаться ко мне.

Ответы [ 3 ]

0 голосов
/ 27 октября 2010

Если вам нужно манипулировать состоянием компонентов Swing и вы не уверены, что ваш код работает в EDT, SwingUtilities.invokeAndWait () и SwingUtilities.invokeLater () может помочь

0 голосов
/ 27 октября 2010

Следующий класс проверяет нарушения EDT. Установите его перед выполнением любого другого кода, связанного с GUI, следующим образом:

RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager());

Вот класс:

import javax.swing.JComponent;
import javax.swing.RepaintManager;
import javax.swing.SwingUtilities;

public class CheckThreadViolationRepaintManager extends RepaintManager {
    private boolean completeCheck = true;

    public synchronized void addInvalidComponent(JComponent component) {
        checkThreadViolations(component);
        super.addInvalidComponent(component);
    }

    public boolean isCompleteCheck() {
        return completeCheck;
    }

    public void setCompleteCheck(boolean completeCheck) {
        this.completeCheck = completeCheck;
    }

    public void addDirtyRegion(JComponent component, int x, int y, int w, int h) {
        checkThreadViolations(component);
        super.addDirtyRegion(component, x, y, w, h);
    }

    private void checkThreadViolations(JComponent c) {
        if (!SwingUtilities.isEventDispatchThread() && (completeCheck || c.isShowing())) {
            Exception exception = new Exception("EDT Violation");
            boolean repaint = false;
            boolean fromSwing = false;
            StackTraceElement[] stackTrace = exception.getStackTrace();
            for (StackTraceElement st : stackTrace) {
                if (repaint && st.getClassName().startsWith("javax.swing.")) {
                    fromSwing = true;
                }
                if ("repaint".equals(st.getMethodName())) {
                    repaint = true;
                }
            }
            if (repaint && !fromSwing) {
                //no problems here, since repaint() is thread safe
                return;
            }
            exception.printStackTrace();
        }
    }
}
0 голосов
/ 27 октября 2010

Вы уверены, что весь код пользовательского интерфейса выполняется в EDT?Если нет, попробуйте установить только для тестирования Substance Look & Feel .Это вызывает исключение в случае выполнения кода пользовательского интерфейса в другом потоке.

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