2009-07-08 3 views
191

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

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

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

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

+5

[Этот учебник от Oracle] (http://docs.oracle.com/javase/tutorial/uiswing/components/jcomponent.html # custompaintingapi): «Всегда вызывать перерисовку после повторной проверки». Однако никаких объяснений не предусмотрено. – mins

ответ

140

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

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

+1

Не могли бы вы объяснить, почему создание новой панели - лучшее решение, чем использование старого? :) – Arttu

+2

@Arttu - это меньше работает, и поэтому менее подвержено ошибкам. – kdgregory

55

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

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

79

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

validate(); 
    repaint(); 

после того, как вы завершили надстройку() ИНГ новые компоненты.

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

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

-4

да вам необходимо позвонить по телефону repaint(); revalidate(); при вызове RemoveAll(), то вы должны вызвать перерисовку() и перепроверить()

+9

И это отличается от принятого ответа как? – William

1

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

Смежные вопросы