Java Swing revalidate () против repaint ()

211

Я собираю приложение Swing, где я часто хочу заменить содержимое JPanel. Для этого я звоню removeAll(), затем добавляю новый контент, затем звоню revalidate().

Однако я обнаружил, что старый контент все еще действительно виден (хотя и скрыт новым). Если я добавлю вызов repaint()в дополнение к revalidate(), он работает как ожидалось.

Я уверен, что в других случаях я чувствовал, что revalidate()достаточно просто позвонить .

Итак, в основном мой вопрос - мне нужно вызывать обе функции, а если нет, то когда мне следует вызывать каждую из них?

Уильям
источник
6
Это руководство от Oracle гласит: «Всегда вызывать перекрашивание после повторной проверки». Никаких объяснений не приводится.
мин

Ответы:

154

Вам нужно позвонить repaint()и revalidate(). Первый говорит Swing, что область окна грязная (что необходимо, чтобы стереть изображение старых детей, удаленных removeAll()); последний говорит менеджеру компоновки пересчитать компоновку (что необходимо при добавлении компонентов). Это должно привести к перекрашиванию дочерних элементов панели, но не может заставить саму панель сделать это (см. Это для списка перекрашивать триггера).

На более общей ноте: вместо того, чтобы повторно использовать исходную панель, я бы порекомендовал создать новую панель и поменять их местами на родительской.

kdgregory
источник
1
Не могли бы вы объяснить, почему создание новой панели является лучшим решением, чем использование старой? :)
Артту
3
@Arttu - это меньше работы и, следовательно, меньше подвержено ошибкам.
kdgregory
86

Каждый раз, когда вы делаете remove () или removeAll (), вы должны вызывать

  validate();
  repaint();

после завершения добавления () новых компонентов.

Вызов validate () или revalidate () является обязательным, когда вы выполняете remove () - см. Соответствующие javadocs.

Мое собственное тестирование показывает, что repaint () также необходим. Я не уверен, почему именно.

Ноэль Грандин
источник
59

revalidateвызывается для контейнера после добавления новых компонентов или удаления старых. этот вызов является инструкцией, чтобы сказать менеджеру макета выполнить сброс на основе нового списка компонентов. revalidateвызовет перерисовку того, что компонент считает «грязными регионами». Очевидно, что не все регионы на вашей территории JPanelсчитаются грязными RepaintManager.

repaintиспользуется, чтобы сказать компоненту перекрасить себя. Часто бывает так, что вам нужно позвонить, чтобы исправить такие условия, как у вас.

АКФ
источник
5

revalidate()просто запросить компоновку контейнера, когда вы сталкивались с простым вызовом revalidate()работ, это может быть вызвано обновлением границ дочерних компонентов, repaint()когда их границы изменяются во время перекомпоновки. В случае , если вы упомянули, только компонент удаляется и никаких границы компонентов не изменяются, то этот случай не repaint()является «случайно» срабатывает.

Энтони Нг
источник
-4

да, вам нужно вызвать repaint (); перепроверить (); когда вы вызываете removeAll (), тогда вы должны вызвать repaint () и revalidate ()

Сом адхикари
источник