การใช้โหมดเกลียว Swingworker
เป็นสิ่งสำคัญมากสำหรับนักพัฒนาแกว่งที่จะใช้พร้อมกันอย่างรอบคอบ โปรแกรมการแกว่งที่ดีใช้กลไกการทำงานร่วมกันเพื่อสร้างส่วนต่อประสานผู้ใช้ที่ไม่สูญเสียการตอบสนอง - ไม่ว่าการโต้ตอบของผู้ใช้ประเภทใดโปรแกรมจะตอบสนองได้เสมอ ในการสร้างโปรแกรมตอบสนองนักพัฒนาต้องเรียนรู้วิธีการใช้มัลติเธรดในกรอบการแกว่ง
นักพัฒนาวงสวิงจะจัดการกับเธรดประเภทต่อไปนี้:
(1) เธรดเริ่มต้นเธรดดังกล่าวจะเรียกใช้รหัสแอปพลิเคชันเริ่มต้น
(2) เธรดการจัดส่งเหตุการณ์รหัสการประมวลผลเหตุการณ์ทั้งหมดจะดำเนินการที่นี่ รหัสส่วนใหญ่ที่โต้ตอบกับเฟรมเวิร์กสวิงจะต้องดำเนินการเธรดนี้เช่นกัน
(3) เธรดคนงานหรือที่รู้จักกันในชื่อเธรดพื้นหลังจะทำงานได้ตลอดเวลา
นักพัฒนาไม่จำเป็นต้องสร้างเธรดเหล่านี้อย่างชัดเจนในรหัสของพวกเขา: พวกเขาได้รับการจัดเตรียมโดย Runtime หรือ Swing Framework งานของนักพัฒนาคือการใช้เธรดเหล่านี้เพื่อสร้างโปรแกรมการแกว่งที่ตอบสนองและตอบสนองได้
เช่นเดียวกับโปรแกรมอื่น ๆ ทั้งหมดที่ทำงานบนแพลตฟอร์ม Java โปรแกรมสวิงสามารถสร้างเธรดเพิ่มเติมและพูลเธรดซึ่งต้องใช้วิธีการที่จะนำมาใช้ในบทความนี้ บทความนี้จะแนะนำสามเธรดข้างต้น การอภิปรายของเธรดคนงานจะเกี่ยวข้องกับการใช้คลาส Javax.swing.swingworker คลาสนี้มีคุณสมบัติที่มีประโยชน์มากมายรวมถึงการสื่อสารและการทำงานร่วมกันระหว่างงานเธรดคนงานและงานเธรดอื่น ๆ
1. เธรดเริ่มต้น
แต่ละโปรแกรมสร้างชุดของเธรดที่จุดเริ่มต้นของตรรกะแอปพลิเคชัน ในโปรแกรมมาตรฐานมีเพียงหนึ่งเธรดดังกล่าว: เธรดนี้จะเรียกวิธีการหลักในคลาสหลักของโปรแกรม ในแอปเพล็ตเธรดเริ่มต้นเป็นตัวสร้างของวัตถุแอปเพล็ตซึ่งจะเรียกวิธีการเริ่มต้น การกระทำเหล่านี้อาจถูกดำเนินการในเธรดเดียวหรือในสองหรือสามเธรดที่แตกต่างกันทั้งหมดขึ้นอยู่กับการใช้งานเฉพาะของแพลตฟอร์ม Java ในบทความนี้เราเรียกเธรดเธรดประเภทนี้
ในโปรแกรมการแกว่งมีไม่มากที่จะทำในเธรดเริ่มต้น งานพื้นฐานที่สุดของพวกเขาคือการสร้างวัตถุที่เรียกใช้งานได้ซึ่งเริ่มต้น GUI และจัดเตรียมวัตถุที่ใช้ในการดำเนินการเหตุการณ์ในเธรดการส่งเหตุการณ์ เมื่อ GUI ถูกสร้างขึ้นโปรแกรมจะถูกขับเคลื่อนโดยกิจกรรม GUI เป็นหลักซึ่งแต่ละรายการจะทำให้เกิดการดำเนินการของเหตุการณ์ในเธรดการส่งเหตุการณ์ รหัสโปรแกรมสามารถจัดทำภารกิจเพิ่มเติมไปยังเธรดที่ขับเคลื่อนด้วยเหตุการณ์ (โดยมีเงื่อนไขว่าพวกเขาจะดำเนินการอย่างรวดเร็วเพื่อที่พวกเขาจะไม่เข้าไปยุ่งเกี่ยวกับการประมวลผลเหตุการณ์) หรือสร้างเธรดคนงาน (ใช้ในการทำงานที่ต้องใช้เวลานาน)
ภารกิจการสร้าง GUI ของวงดนตรีเริ่มต้นคือการโทรหา javax.swing.swingutilities.invokelater หรือ javax.swing.swingutilities.invokeandwait ทั้งสองวิธีใช้พารามิเตอร์ที่ไม่ซ้ำกัน: Runnable ใช้เพื่อกำหนดงานใหม่ ความแตกต่างเพียงอย่างเดียวระหว่างพวกเขาคือ: Invokerlater เท่านั้นจัดงานและผลตอบแทนเท่านั้น Invokeandwait จะรอให้งานดำเนินการก่อนที่จะกลับมา
ดูตัวอย่างต่อไปนี้:
swingutilities.invokelater (ใหม่ runnable ()) {public void run () {createandshowgui (); - ในแอปเพล็ตภารกิจในการสร้าง GUI จะต้องใส่ลงในวิธีการเริ่มต้นและใช้ invokeandwait; มิฉะนั้นกระบวนการเริ่มต้นจะเป็นไปได้ก่อนที่จะสร้าง GUI ซึ่งอาจทำให้เกิดปัญหา ในกรณีอื่น ๆ งานการสร้าง GUI มักจะเป็นงานสุดท้ายในเธรดเริ่มต้นที่จะดำเนินการดังนั้นทั้งสองใช้ invokelater หรือ invokeandwait
ทำไมเธรดเริ่มต้นไม่สร้าง GUI โดยตรง? เนื่องจากรหัสเกือบทั้งหมดที่ใช้ในการสร้างและโต้ตอบกับส่วนประกอบสวิงจะต้องดำเนินการในเธรดการส่งเหตุการณ์ ข้อ จำกัด นี้จะกล่าวถึงด้านล่าง
2. เธรดการกระจายเหตุการณ์
รหัสการประมวลผลของเหตุการณ์การแกว่งจะถูกดำเนินการในเธรดพิเศษซึ่งเรียกว่าเธรดการส่งเหตุการณ์ รหัสส่วนใหญ่ที่เรียกว่าวิธีการแกว่งจะถูกดำเนินการในเธรดนี้ สิ่งนี้จำเป็นเพราะวัตถุสวิงส่วนใหญ่เป็น "ไม่ปลอดภัย"
คุณสามารถนึกถึงการดำเนินการของรหัสว่าเป็นการทำงานชุดสั้น ๆ ในเธรดการส่งเหตุการณ์ งานส่วนใหญ่เรียกโดยวิธีการจัดการเหตุการณ์เช่น ActionListener.actionPerformed งานที่เหลือจะได้รับการจัดเตรียมโดยรหัสโปรแกรมโดยใช้ Invokelater หรือ Invokeandwait งานในเธรดการจัดส่งเหตุการณ์จะต้องสามารถดำเนินการได้อย่างรวดเร็ว มิฉะนั้นเหตุการณ์ที่ไม่ได้ประมวลผลจะถูก backlogged และส่วนต่อประสานผู้ใช้จะกลายเป็น "ตอบสนอง"
หากคุณต้องการตรวจสอบว่ารหัสของคุณถูกดำเนินการในเธรดการส่งเหตุการณ์หรือไม่โทร javax.swing.swingutilities.iseventDispatchThread
3. เธรดคนงานและผู้ฝึกสวิง
เมื่อโปรแกรมการแกว่งจำเป็นต้องทำงานที่ยาวนานมันมักจะทำโดยใช้เธรดคนงาน แต่ละงานจะดำเนินการในเธรดคนงานซึ่งเป็นอินสแตนซ์ของคลาส Javax.swing.swingworker คลาส Swingworker เป็นคลาสนามธรรม คุณต้องกำหนดคลาสย่อยเพื่อสร้างวัตถุ Swingworker มักจะใช้คลาสภายในที่ไม่ระบุชื่อเพื่อทำสิ่งนี้
Swingworker มีคุณสมบัติการสื่อสารและการควบคุม:
(1) คลาสย่อยของ Swingworker สามารถกำหนดวิธีการทำ เมื่องานพื้นหลังเสร็จสมบูรณ์จะมีการเรียกโดยอัตโนมัติโดยเธรดการจัดส่งเหตุการณ์
(2) คลาส Swingworker ใช้ java.util.concurrent.future อินเทอร์เฟซนี้ช่วยให้งานพื้นหลังสามารถส่งคืนค่ากลับไปยังเธรดอื่น ๆ วิธีการในอินเทอร์เฟซนี้ยังให้ฟังก์ชั่นที่อนุญาตให้ยกเลิกงานพื้นหลังและตรวจสอบว่างานพื้นหลังเสร็จสมบูรณ์หรือเพิกถอนหรือไม่
(3) งานพื้นหลังสามารถให้ผลลัพธ์ระดับกลางได้โดยเรียก Swingworker.Publish และเธรดการจัดส่งเหตุการณ์จะเรียกวิธีนี้
(4) งานพื้นหลังสามารถกำหนดคุณสมบัติการผูกมัด การเปลี่ยนแปลงในแอตทริบิวต์การเชื่อมโยงจะทริกเกอร์เหตุการณ์และเธรดการส่งเหตุการณ์จะเรียกตัวจัดการเหตุการณ์เพื่อจัดการเหตุการณ์ที่เกิดขึ้นเหล่านี้
4. งานแบ็กเอนด์ที่เรียบง่าย
นี่คือตัวอย่างงานนี้ง่ายมาก แต่เป็นงานที่อาจใช้เวลานาน TumbleItem Applet นำเข้าไฟล์รูปภาพ หากไฟล์รูปภาพเหล่านี้ถูกนำเข้าผ่านเธรดเริ่มต้นจะมีความล่าช้าก่อนที่ GUI จะปรากฏขึ้น หากไฟล์รูปภาพเหล่านี้ถูกนำเข้าในเธรดการส่งเหตุการณ์ GUI อาจไม่ตอบกลับชั่วคราว
เพื่อแก้ปัญหาเหล่านี้คลาส TumbleItem จะสร้างและดำเนินการอินสแตนซ์ของคลาส Stringworker เมื่อเริ่มต้น วิธีการ doinbackground ของวัตถุนี้ดำเนินการในเธรดคนงานนำเข้าภาพไปยังอาร์เรย์ Imageicon และส่งคืนการอ้างอิงไปยังมัน จากนั้นวิธีการที่เสร็จสิ้นจะถูกดำเนินการในเธรดการส่งเหตุการณ์รับการอ้างอิงที่ส่งคืนและใส่ไว้ใน IMG ตัวแปรของสมาชิกของคลาส Applet การทำเช่นนี้ช่วยให้คลาส TumbleItem สร้าง GUI ได้ทันทีโดยไม่ต้องรอการนำเข้าภาพให้เสร็จสมบูรณ์
รหัสตัวอย่างต่อไปนี้กำหนดและใช้วัตถุ Swingworker
Swingworker Worker = New Swingworker <Imageicon [], void> () {@Override Public ImageIcon [] doinbackground () {สุดท้าย imageicon [] innerimgs = ใหม่ Imageicon [nimgs]; สำหรับ (int i = 0; i <nimgs; i ++) {innerimgs [i] = loadimage (i+1); } return innerimgs; } @Override โมฆะสาธารณะทำ () {// ลบป้ายกำกับ "การโหลดภาพ" Animator.removeAll (); loopslot = -1; ลอง {imgs = get (); } catch (interruptedException ละเว้น) {} catch (java.util.concurrent.executionException e) {string ทำไม = null; สาเหตุที่โยนได้ = e.getCause (); ถ้า (สาเหตุ! = null) {ทำไม = cause.getMessage (); } else {ทำไม = e.getMessage (); } system.err.println ("การดึงข้อผิดพลาดไฟล์:" + ทำไม); - คลาสย่อยทั้งหมดที่สืบทอดมาจาก Swingworker จะต้องใช้ doinbackground; การใช้วิธีการเสร็จเป็นทางเลือก
โปรดทราบว่า Swingworker เป็นคลาสกระบวนทัศน์ที่มีสองพารามิเตอร์ พารามิเตอร์ประเภทแรกระบุประเภทการส่งคืนของ doinbackground นอกจากนี้ยังเป็นประเภทของวิธีการรับซึ่งสามารถเรียกได้โดยเธรดอื่น ๆ เพื่อให้ได้ค่าส่งคืนจาก doinbackground พารามิเตอร์ประเภทที่สองระบุประเภทของผลลัพธ์กลาง ตัวอย่างนี้ไม่ส่งคืนผลลัพธ์ระดับกลางดังนั้นจึงถูกตั้งค่าเป็นโมฆะ
การใช้วิธี GET คุณสามารถใช้การอ้างอิงไปยังวัตถุ IMGs (สร้างขึ้นในเธรดคนงาน) ในเธรดการส่งเหตุการณ์ สิ่งนี้ช่วยให้การแชร์วัตถุระหว่างเธรด
จริงๆแล้วมีสองวิธีในการให้วัตถุที่ส่งคืนโดยคลาส doinbackground
(1) ไม่มีพารามิเตอร์ที่จะเรียก Swingworker.get หากงานพื้นหลังยังไม่เสร็จสมบูรณ์เมธอดจะบล็อกจนกว่าจะเสร็จสิ้น
(2) การโทร Swingworker.gat ด้วยพารามิเตอร์เพื่อระบุการหมดเวลา หากงานพื้นหลังยังไม่เสร็จสมบูรณ์ให้บล็อกจนกว่าจะเสร็จสิ้น - เว้นแต่ว่าการหมดเวลาจะหมดอายุซึ่งในกรณีนี้จะได้รับการโยน java.util.concurrent.timeoutException
5. งานที่มีผลลัพธ์ระดับกลาง
มันมีประโยชน์ที่จะมีงานแบ็กเอนด์ที่ทำงานให้ผลลัพธ์ระดับกลาง งานแบ็กเอนด์สามารถโทรหาวิธีการสวิงเวิร์คเกอร์วิธีการเผยแพร่เพื่อทำสิ่งนี้ วิธีนี้ยอมรับพารามิเตอร์จำนวนมาก แต่ละพารามิเตอร์จะต้องเป็นหนึ่งที่ระบุโดยพารามิเตอร์ประเภทที่สองของ Swingworker
Swingworker.process สามารถแทนที่เพื่อบันทึกผลลัพธ์ที่ได้จากวิธีการเผยแพร่ วิธีนี้เรียกโดยเธรดการจัดส่งเหตุการณ์ ชุดผลลัพธ์จากวิธีการเผยแพร่มักจะถูกรวบรวมโดยวิธีกระบวนการ
มาดูตัวอย่างที่จัดทำโดย filpper.java โปรแกรมนี้สร้างชุดของการทดสอบบูลีนแบบสุ่ม java.util.random ผ่านงานพื้นหลัง มันเหมือนการทดลองขว้างเหรียญ ในการรายงานผลลัพธ์งานพื้นหลังใช้วัตถุ Flippair
ชั้นเรียนคงที่คลาสส่วนตัว flippair {หัวยาวสุดท้ายรวมทั้งหมด; Flippair (หัวยาวรวม) {this.heads = heads; this.total = ทั้งหมด; - หัวแสดงผลลัพธ์ของความจริง; ทั้งหมดแสดงถึงจำนวนการโยนทั้งหมด
โปรแกรมพื้นหลังเป็นอินสแตนซ์ของ Filptask:
คลาสส่วนตัว Fliptask ขยาย Swingworker <Void, Flippair> {
เนื่องจากงานไม่ส่งคืนผลลัพธ์สุดท้ายจึงไม่จำเป็นต้องระบุว่าพารามิเตอร์ประเภทแรกคือใช้โมฆะ หลังจาก "การขว้างปา" แต่ละครั้งงานจะเผยแพร่:
@OverrideProtected void doinbackground () {heads ยาว = 0; ยาวทั้งหมด = 0; สุ่มสุ่ม = ใหม่สุ่ม (); ในขณะที่ (! iscancelled ()) {Total ++; if (random.nextboolean ()) {heads ++; } เผยแพร่ (New Flippair (หัวทั้งหมด)); } return null;} เนื่องจากการเผยแพร่มักเรียกว่าค่า flippair จำนวนมากจะถูกรวบรวมก่อนที่วิธีกระบวนการจะถูกเรียกโดยเธรดการจัดส่งเหตุการณ์ กระบวนการมุ่งเน้นเฉพาะชุดของค่าสุดท้ายที่ส่งคืนในแต่ละครั้งและใช้เพื่ออัปเดต GUI:
กระบวนการโมฆะที่ได้รับการป้องกัน (รายการคู่) {flippair pair = pairs.get (pairs.size () - 1); headstext.settext (string.format ("%d", pair.heads)); TotalText.settext (string.format ("%d", pair.total)); devtext.settext (string.format ("%. 10g", ((double) pair.heads)/((double) pair.total) - 0.5));} 6. ยกเลิกงานพื้นหลัง
โทรหา Swingworker.cancel เพื่อยกเลิกงานพื้นหลังที่ดำเนินการ งานจะต้องสอดคล้องกับกลไกการเลิกทำของตัวเอง มีสองวิธีในการทำเช่นนี้:
(1) เมื่อได้รับการขัดจังหวะมันจะถูกยกเลิก
(2) โทรหา Swingworker.isceled หากการโทร Swingworker ยกเลิกวิธีการจะส่งคืนจริง
7. ผูกแอตทริบิวต์และวิธีการสถานะ
Swingworker รองรับคุณสมบัติที่ถูกผูกไว้ซึ่งมีประโยชน์มากเมื่อสื่อสารกับเธรดอื่น ๆ ให้คุณสมบัติที่มีผลผูกพันสองประการ: ความคืบหน้าและสถานะ ความคืบหน้าและสถานะสามารถใช้เพื่อทริกเกอร์งานการประมวลผลเหตุการณ์ในเธรดการส่งเหตุการณ์
โดยการใช้ผู้ฟังการเปลี่ยนแปลงคุณสมบัติโปรแกรมสามารถจับการเปลี่ยนแปลงระหว่างความคืบหน้าสถานะหรือคุณสมบัติการเชื่อมโยงอื่น ๆ
7.1 ตัวแปรที่ถูกผูกไว้
ตัวแปรการเชื่อมโยงความคืบหน้าเป็นตัวแปรจำนวนเต็มที่มีช่วง 0 ถึง 100 มันกำหนดไว้ล่วงหน้าสำหรับผู้ตั้งค่าล่วงหน้า
7.2 ตัวแปรที่ถูกผูกไว้ของรัฐ
การเปลี่ยนแปลงในตัวแปรที่มีผลผูกพันสถานะสะท้อนกระบวนการของการเปลี่ยนวัตถุสวิงเวิร์คเกอร์ในช่วงวงจรชีวิต ตัวแปรนี้มีประเภทการแจงนับของ Swingworker.statevalue ค่าที่เป็นไปได้คือ:
(1) รอดำเนินการ
สถานะนี้ใช้เวลานานในการรู้จากการสร้างวัตถุที่เรียกว่าวิธี doinbackground
(2) เริ่มต้น
สถานะนี้ใช้เวลาสักครู่ก่อนที่วิธีการ doinbackground จะถูกเรียกจนกว่าจะมีการเรียกวิธีการเสร็จสิ้น
(3) ทำ
เวลาที่เหลืออยู่ที่วัตถุมีอยู่จะยังคงอยู่ในสถานะนี้
หากคุณต้องการส่งคืนค่าของสถานะปัจจุบันคุณสามารถโทรหา Swingworker.getState
7.3status วิธีการ
สองวิธีที่จัดทำโดยอินเทอร์เฟซในอนาคตสามารถรายงานสถานะของงานพื้นหลังได้ หากงานถูกยกเลิก iscancelled จะกลับมาเป็นจริง นอกจากนี้หากงานเสร็จสมบูรณ์เช่นมันจะเสร็จสมบูรณ์ตามปกติหรือถูกยกเลิก ISDONE จะกลับมาเป็นจริง
การใช้คอนเทนเนอร์ระดับบนสุด
Swing มีคลาสคอนเทนเนอร์ระดับบน 3 คลาส: JFrame, JDialog, Japplet เมื่อใช้คลาสทั้งสามนี้คุณต้องใส่ใจกับประเด็นต่อไปนี้:
(1). เพื่อที่จะแสดงบนหน้าจอองค์ประกอบ GUI แต่ละตัวจะต้องเป็นส่วนหนึ่งของลำดับชั้นที่มีอยู่ ลำดับชั้นการรวมเป็นโครงสร้างต้นไม้ของส่วนประกอบและคอนเทนเนอร์ระดับบนสุดคือรากของมัน
(2). แต่ละองค์ประกอบ GUI สามารถรวมได้เพียงครั้งเดียว หากส่วนประกอบอยู่ในคอนเทนเนอร์แล้วพยายามเพิ่มลงในคอนเทนเนอร์ใหม่ส่วนประกอบจะถูกลบออกจากคอนเทนเนอร์แรกและเพิ่มลงในคอนเทนเนอร์ที่สอง
(3). แต่ละคอนเทนเนอร์ระดับบนสุดมีบานหน้าต่างเนื้อหา โดยทั่วไปแผงเนื้อหานี้จะมี (โดยตรงหรือโดยอ้อม) ส่วนประกอบภาพทั้งหมดของ GUI คอนเทนเนอร์ระดับบนสุด
(4). คุณสามารถเพิ่มแถบเมนูลงในคอนเทนเนอร์ด้านบน โดยปกติแล้วแถบเมนูนี้จะถูกวางไว้ในคอนเทนเนอร์ด้านบน แต่อยู่นอกแผงเนื้อหา
1. คอนเทนเนอร์ระดับบนสุดและลำดับชั้นการรวม
แต่ละโปรแกรมที่ใช้องค์ประกอบการแกว่งมีคอนเทนเนอร์ระดับบนสุดอย่างน้อยหนึ่งรายการ คอนเทนเนอร์ระดับบนสุดนี้เป็นโหนดรูทที่มีลำดับชั้น-ลำดับชั้นนี้จะมีส่วนประกอบสวิงทั้งหมดที่จะปรากฏในคอนเทนเนอร์ระดับบนสุดนี้
โดยทั่วไปแล้วแอปพลิเคชันที่ใช้ GUI แบบแกว่งแยกต่างหากมีลำดับชั้นการรวมอย่างน้อยหนึ่งลำดับและโหนดรูทของมันคือ JFrame ตัวอย่างเช่นหากแอปพลิเคชันมีหนึ่งหน้าต่างและกล่องโต้ตอบสองกล่องแอปพลิเคชันจะมีสามระดับการรวมนั่นคือจะมีคอนเทนเนอร์ระดับบนสุดสามคอนเทนเนอร์ ลำดับชั้นการบรรจุใช้ JFrame เป็นโหนดรูทและลำดับชั้นการบรรจุอีกสองลำดับแต่ละอันมี jdialog เป็นโหนดรูท
แอปเพล็ตที่ใช้ส่วนประกอบการแกว่งมีลำดับชั้นการรวมอย่างน้อยหนึ่งลำดับและสามารถพิจารณาได้ว่าหนึ่งในนั้นจะต้องทำด้วย japplet เป็นโหนดรากของมัน ตัวอย่างเช่นแอปเพล็ตที่มีกล่องโต้ตอบมันจะมีสองระดับการรวม ส่วนประกอบในหน้าต่างเบราว์เซอร์จะถูกวางไว้ในลำดับชั้นการบรรจุและโหนดรูทเป็นวัตถุ Japplet กล่องโต้ตอบจะมีลำดับชั้นที่มีอยู่และโหนดรูทเป็นวัตถุ JDialog
2. เพิ่มส่วนประกอบลงในแผงเนื้อหา
การดำเนินการโค้ดต่อไปนี้คือการรับแผงเนื้อหาของเฟรมในตัวอย่างด้านบนและเพิ่มฉลากสีเหลือง:
frame.getContentPane (). เพิ่ม (Yellowlabel, BorderLayout.Center);
ดังที่แสดงในรหัสคุณต้องค้นหาแผงเนื้อหาของคอนเทนเนอร์ระดับบนสุดก่อนและนำไปใช้ผ่านวิธี GetContentPane แผงเนื้อหาเริ่มต้นเป็นคอนเทนเนอร์ระดับกลางที่ง่ายซึ่งสืบทอดมาจาก JComponent โดยใช้ BorderLayout เป็นตัวจัดการพาเนล
การปรับแต่งแผงเนื้อหานั้นง่าย - ตั้งค่าตัวจัดการแผงหรือเพิ่มเส้นขอบ จะต้องมีการบันทึกไว้ที่นี่ว่าวิธี getContentPane จะส่งคืนวัตถุคอนเทนเนอร์ไม่ใช่วัตถุ JComponent ซึ่งหมายความว่าหากคุณต้องการใช้ประโยชน์จากฟังก์ชันการทำงานของ JComponent บางส่วนคุณต้องพิมพ์การแปลงค่าส่งคืนหรือสร้างส่วนประกอบของคุณเองเป็นแผงเนื้อหา ตัวอย่างของเรามักจะใช้วิธีที่สอง เพราะวิธีที่สองนั้นชัดเจนและชัดเจนยิ่งขึ้น อีกวิธีหนึ่งที่เราใช้คือการเพิ่มส่วนประกอบที่กำหนดด้วยตนเองในแผงเนื้อหาเพื่อครอบคลุมแผงเนื้อหาอย่างสมบูรณ์
หากคุณสร้างแผงเนื้อหาของคุณเองให้ระวังเพื่อให้แน่ใจว่าเป็นทึบแสง jpanel ทึบแสงจะเป็นตัวเลือกที่ดี โปรดทราบว่าโดยค่าเริ่มต้นเค้าโครงของ JPanel ได้รับการจัดการเป็น flowlayout และคุณอาจต้องการแทนที่ด้วยตัวจัดการเค้าโครงอื่น
เพื่อให้ส่วนประกอบเป็นแผงเนื้อหาคุณต้องใช้วิธี SetContentPane ของคอนเทนเนอร์ระดับบนสุดเช่น:
// สร้างพาเนลและเพิ่มส่วนประกอบลงใน it.jPanel ContentPane = new JPanel (ใหม่ BorderLayout ()); ContentPane.SetBorder (symerover); contentPane.add (somecomponent, borderlayout.center); contentPane.add pane.//contentpane.setopaque(true);toplevelcontainer.setContentPane(ContentPane);
หมายเหตุ: อย่าใช้คอนเทนเนอร์โปร่งใสเป็นแผงเนื้อหาเช่น JScrollpane, JSplitpane และ JTabbedpane แผงเนื้อหาที่โปร่งใสจะทำให้ส่วนประกอบสับสน แม้ว่าคุณสามารถสร้างส่วนประกอบสวิงที่โปร่งใสใด ๆ ผ่านวิธี Setopaque (TRUE) แต่มันจะไม่ถูกต้องเมื่อส่วนประกอบบางส่วนถูกตั้งค่าให้ทึบแสงอย่างสมบูรณ์ ตัวอย่างเช่นแผงแท็ก
3. การเพิ่มแถบเมนู
ในทางทฤษฎีคอนเทนเนอร์ระดับบนสุดสามารถมีแถบเมนู แต่ข้อเท็จจริงแสดงให้เห็นว่าแถบเมนูจะปรากฏในเฟรมหรือแอปเพล็ตเท่านั้น ในการเพิ่มแถบเมนูลงในคอนเทนเนอร์ระดับบนสุดคุณต้องสร้างวัตถุ JMenubar ประกอบเมนูบางอย่างแล้วเรียกใช้วิธี SetjMenubar อินสแตนซ์ topleveldemo เพิ่มแถบเมนูลงในเฟรมผ่านรหัสต่อไปนี้
frame.setjmenubar (Cyanmenubar);
4. บานหน้าต่างราก
แต่ละคอนเทนเนอร์ระดับบนสุดขึ้นอยู่กับคอนเทนเนอร์กลางโดยนัยที่เรียกว่าคอนเทนเนอร์รูท คอนเทนเนอร์รูทนี้จัดการแผงเนื้อหาและแถบเมนูพร้อมกับภาชนะอื่น ๆ สองตัวขึ้นไป (ดูบานหน้าต่างชั้น ฯลฯ ) คุณไม่จำเป็นต้องรู้เกี่ยวกับการใช้คอนเทนเนอร์รูทองค์ประกอบสวิง อย่างไรก็ตามหากคุณต้องการสกัดกั้นการคลิกเมาส์หรือวาดบนส่วนประกอบหลายส่วนคุณต้องรู้คอนเทนเนอร์รูท
ข้างต้นได้รับการอธิบายเกี่ยวกับแผงเนื้อหาและแถบเมนูเสริมและจะไม่ถูกทำซ้ำที่นี่ อีกสององค์ประกอบที่มีอยู่ในคอนเทนเนอร์รูทคือแผงเลย์เอาต์และแผงกระจก แผงเลย์เอาต์มีแผงเมนูและแผงเนื้อหาโดยตรงและช่วยให้คุณสามารถเรียงลำดับส่วนประกอบอื่น ๆ ที่เพิ่มโดยพิกัด Z แผงกระจกมักจะใช้เพื่อสกัดกั้นการกระทำที่เกิดขึ้นในชั้นบนสุดและยังสามารถใช้ในการวาดส่วนประกอบหลายส่วน