Java Swing memvalidasi ulang () vs mengecat ulang ()

211

Saya menyusun aplikasi Swing di mana saya sering ingin mengganti konten JPanel. Untuk melakukan ini, saya menelepon removeAll(), lalu menambahkan konten baru, lalu menelepon revalidate().

Namun saya menemukan bahwa konten lama masih benar-benar terlihat (meskipun dikaburkan oleh konten baru). Jika saya menambahkan panggilan ke repaint()selain revalidate(), itu berfungsi seperti yang diharapkan.

Saya yakin pada kesempatan lain saya pernah mengalami bahwa menelepon saja revalidate()sudah cukup.

Jadi pada dasarnya pertanyaan saya adalah - apakah saya harus memanggil kedua fungsi dan jika tidak, kapan saya harus memanggil masing-masing fungsi?

William
sumber
6
Tutorial dari Oracle ini menyatakan: "Selalu panggil pengecatan ulang setelah divalidasi ulang". Tidak ada penjelasan yang diberikan.
mnt

Jawaban:

154

Anda perlu menelepon repaint()dan revalidate(). Yang pertama memberitahu Swing bahwa area jendela itu kotor (yang diperlukan untuk menghapus gambar anak-anak yang sudah dihapus removeAll()); yang terakhir memberitahu manajer tata letak untuk menghitung ulang tata letak (yang diperlukan saat menambahkan komponen). Ini seharusnya menyebabkan anak - anak dari panel mengecat ulang, tetapi mungkin tidak menyebabkan panel itu sendiri melakukannya (lihat ini untuk daftar pemicu pengecatan ulang).

Pada catatan yang lebih umum: daripada menggunakan kembali panel asli, saya akan merekomendasikan membangun panel baru dan menukarnya dengan orang tua.

kdgregory
sumber
1
Bisakah Anda merasionalisasi mengapa membangun panel baru adalah solusi yang lebih baik daripada menggunakan yang lama? :)
Arttu
3
@ Arttu - ini kurang bekerja, dan karena itu kurang rentan terhadap kesalahan.
kdgregory
86

Setiap kali Anda melakukan remove () atau removeAll (), Anda harus menelepon

  validate();
  repaint();

setelah Anda selesai menambahkan () komponen baru.

Memvalidasi panggilan () atau memvalidasi ulang () wajib dilakukan saat Anda menghapus () - lihat javadocs yang relevan.

Pengujian saya sendiri menunjukkan bahwa pengecatan ulang () juga diperlukan. Saya tidak yakin persis mengapa.

Noel Grandin
sumber
59

revalidatedipanggil pada wadah setelah komponen baru ditambahkan atau yang lama dihapus. panggilan ini adalah instruksi untuk memberi tahu pengelola tata letak untuk mengatur ulang berdasarkan daftar komponen baru. revalidateakan memicu panggilan untuk mengecat ulang apa yang menurut komponen itu 'daerah kotor'. Jelas tidak semua wilayah pada Anda JPaneldianggap kotor olehRepaintManager .

repaintdigunakan untuk memberitahu komponen untuk mengecat ulang dirinya sendiri. Sering kali Anda perlu menyebutnya untuk membersihkan kondisi seperti milik Anda.

akf
sumber
5

revalidate()cukup minta tata letak wadah, ketika Anda hanya mengalami revalidate()pekerjaan, itu bisa disebabkan oleh pembaruan batas komponen anak memicu repaint()ketika batas mereka diubah selama tata letak ulang. Dalam kasus yang Anda sebutkan, hanya komponen yang dihapus dan tidak ada batasan komponen yang diubah, kasing ini tidak ada repaint()yang "tidak sengaja" dipicu.

Antony Ng
sumber
-4

ya, Anda perlu memanggil pengecatan ulang (); validasi ulang (); ketika Anda memanggil removeAll () maka Anda harus memanggil mengecat () dan memvalidasi ulang ()

Som Adhikari
sumber