Java Swing revalidate() vs repaint()

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

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

В некоторых случаях я уверен, что достаточно просто вызвать revalidate().

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

Ответ 1

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

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

Ответ 2

При удалении() или removeAll() вы должны вызвать

  validate();
  repaint();

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

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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