Przygotowuję aplikację Swing, w której często chcę zastąpić zawartość JPanel. Aby to zrobić, dzwonię removeAll()
, a następnie dodaję nową treść, a następnie dzwonię revalidate()
.
Jednak stwierdzam, że stara treść jest nadal faktycznie widoczna (choć zasłonięta przez nową treść). Jeśli dodam połączenie repaint()
do revalidate()
, działa to zgodnie z oczekiwaniami.
Jestem pewien, że przy innych okazjach doświadczyłem, że wystarczy zadzwonić revalidate()
.
Więc w zasadzie moje pytanie brzmi - czy powinienem wywoływać obie funkcje, a jeśli nie, to kiedy mam wywoływać każdą z nich?
Odpowiedzi:
Musisz zadzwonić
repaint()
irevalidate()
. Ten pierwszy mówi Swingowi, że część okna jest brudna (co jest konieczne, aby usunąć zdjęcie starych dzieci usuniętych przezremoveAll()
); ten ostatni instruuje menedżera układu, aby ponownie obliczył układ (co jest konieczne przy dodawaniu komponentów). Powinno to spowodować dzieci z panelu do odświeżenia, ale nie może powodować sama płyta to zrobić (patrz to na liście wyzwalaczy przemalować).Mówiąc bardziej ogólnie: zamiast ponownie używać oryginalnego panelu, zaleciłbym zbudowanie nowego panelu i zamianę go w obiekcie nadrzędnym.
źródło
Za każdym razem, gdy wykonujesz remove () lub removeAll (), powinieneś wywołać funkcję
po zakończeniu dodawania () nowych komponentów.
Wywołanie validate () lub revalidate () jest obowiązkowe, gdy wykonujesz remove () - zobacz odpowiednie javadocs.
Moje własne testy wskazują, że konieczne jest również odmalowanie (). Nie jestem pewien dokładnie, dlaczego.
źródło
revalidate
jest wywoływany w kontenerze po dodaniu nowych składników lub usunięciu starych. to wywołanie jest instrukcją informującą menedżera układu o konieczności zresetowania na podstawie nowej listy komponentów.revalidate
wywoła wezwanie do odmalowania tego, co składnik uważa za „brudne regiony”. Oczywiście nie wszystkie regiony w twoimJPanel
są uważane za brudne przezRepaintManager
.repaint
służy do informowania komponentu o konieczności odmalowania. Często zdarza się, że musisz to nazwać, aby oczyścić takie warunki, jak twoje.źródło
revalidate()
po prostu prośba o rozmieszczenie kontenera, gdy doświadczyłeś po prostu wywołaniarevalidate()
działa, może to być spowodowane aktualizacją granic komponentów potomnych, które powodują zmianęrepaint()
ich granic podczas zmiany układu. W przypadku, o którym wspomniałeś, tylko komponent został usunięty i nie zostały zmienione żadne granice komponentu, ten przypadek nierepaint()
jest uruchamiany „przypadkowo” .źródło
tak, musisz wywołać repaint (); revalidate (); kiedy wywołasz removeAll (), musisz wywołać repaint () i revalidate ()
źródło