Java Swing revalidate () vs repaint ()


211

ฉันกำลังรวบรวมแอปพลิเคชัน Swing ที่ฉันมักต้องการแทนที่เนื้อหาของ JPanel การทำเช่นนี้ฉันโทรแล้วเพิ่มเนื้อหาใหม่ของฉันแล้วโทรremoveAll()revalidate()

อย่างไรก็ตามฉันพบว่าเนื้อหาเก่ายังคงปรากฏให้เห็นจริง (แม้ว่าจะบดบังด้วยเนื้อหาใหม่) ถ้าฉันเพิ่มสายไปrepaint()เพิ่มเติมจะrevalidate()ทำงานได้ตามที่คาดหวัง

ฉันแน่ใจในโอกาสอื่น ๆ ที่ฉันเคยพบว่าแค่โทรrevalidate()ก็เพียงพอแล้ว

ดังนั้นโดยทั่วไปคำถามของฉันคือ - ฉันควรจะต้องเรียกทั้งฟังก์ชั่นและถ้าไม่ฉันควรจะเรียกพวกเขาเมื่อใด


6
บทช่วยสอนนี้จาก Oracleระบุว่า: "เรียกใช้ทาสีใหม่หลังจากตรวจสอบซ้ำ" ไม่มีคำอธิบายใด ๆ
นาที

คำตอบ:


154

คุณจะต้องเรียกและrepaint() revalidate()อดีตบอกสวิงว่าพื้นที่ของหน้าต่างสกปรก (ซึ่งจำเป็นต้องลบภาพของเด็กเก่าที่ถูกลบโดยremoveAll()) ตัวบอกหลังจะบอกตัวจัดการโครงร่างเพื่อคำนวณโครงร่างอีกครั้ง (ซึ่งจำเป็นเมื่อทำการเพิ่มส่วนประกอบ) สิ่งนี้จะทำให้ลูก ๆของพาเนลทาสีใหม่ แต่อาจไม่ทำให้พาเนลทำเช่นนั้น (ดูสิ่งนี้สำหรับรายการทริกเกอร์การทาสีใหม่)

ในหมายเหตุทั่วไปเพิ่มเติม: แทนที่จะใช้แผงต้นฉบับซ้ำฉันขอแนะนำให้สร้างแผงใหม่และสลับที่แผงควบคุมหลัก


1
คุณสามารถหาเหตุผลเข้าข้างตนเองว่าทำไมการสร้างแผงใหม่จึงเป็นทางออกที่ดีกว่าการใช้แผงแบบเก่า :)
Arttu

3
@Atttt - มันใช้งานได้น้อยลงและมีแนวโน้มที่จะเกิดข้อผิดพลาดน้อยลง
kdgregory

86

ทุกครั้งที่คุณทำการลบ () หรือ removeAll () คุณควรโทร

  validate();
  repaint();

หลังจากคุณเพิ่ม () เสร็จสิ้นเพื่อเพิ่มส่วนประกอบใหม่

การตรวจสอบความถูกต้อง () หรือตรวจสอบใหม่ () เป็นสิ่งจำเป็นเมื่อคุณทำการลบ () - ดู javadocs ที่เกี่ยวข้อง

การทดสอบของฉันเองระบุว่าการวาดใหม่ () เป็นสิ่งจำเป็นเช่นกัน ฉันไม่แน่ใจว่าทำไม


59

revalidateถูกเรียกบนคอนเทนเนอร์เมื่อมีการเพิ่มส่วนประกอบใหม่หรือลบส่วนประกอบเก่าออก การเรียกนี้เป็นคำสั่งเพื่อบอกให้ผู้จัดการโครงร่างทำการรีเซ็ตตามรายการส่วนประกอบใหม่ revalidateจะทำให้การเรียกร้องให้ทาสีใหม่ส่วนประกอบที่คิดว่าเป็น 'บริเวณที่สกปรก' เห็นได้ชัดว่าไม่ทั้งหมดของภูมิภาคบนจะถือว่าสกปรกโดยJPanelRepaintManager

repaintใช้เพื่อบอกส่วนประกอบให้ทาสีใหม่ มันมักจะเป็นกรณีที่คุณต้องเรียกสิ่งนี้เพื่อล้างเงื่อนไขเช่นของคุณ


5

revalidate()เพียงแค่ร้องขอให้จัดวางคอนเทนเนอร์เมื่อคุณประสบกับการเรียกใช้revalidate()งานเพียงอย่างเดียวอาจเกิดจากการอัปเดตขอบเขตขององค์ประกอบย่อยที่เป็นต้นเหตุให้เกิดการrepaint()เปลี่ยนแปลงขอบเขตเมื่อมีการเปลี่ยนแปลงระหว่างการจัดวางใหม่ ในกรณีที่คุณกล่าวถึงเพียงส่วนประกอบลบและไม่มีขอบเขตองค์ประกอบที่มีการเปลี่ยนแปลงกรณีนี้ไม่repaint()เป็น"บังเอิญ"ทริกเกอร์


-4

ใช่คุณต้องโทรทาสี (); revalidate (); เมื่อคุณโทร removeAll () คุณจะต้องโทรหาทาสีใหม่ () และตรวจสอบใหม่ ()

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.