อ่าน 3 นาที
สวิงเวิร์ค
SwingWorker เป็น คลาสยูทิลิตี้ ที่พัฒนาโดย Sun Microsystems สำหรับ ไลบรารี Swing ของ ภาษาการเขียนโปรแกรม Java SwingWorker ช่วยให้สามารถใช้ เธรดการส่งเหตุการณ์ ได้อย่างถูกต้อง...
สวิงเวิร์ค
SwingWorkerเป็นคลาสยูทิลิตี้ที่พัฒนาโดยSun Microsystemsสำหรับ ไลบรารี Swingของภาษาการเขียนโปรแกรม Java SwingWorkerช่วยให้สามารถใช้เธรดการส่งเหตุการณ์ ได้อย่างถูกต้อง ตั้งแต่Java 6 เป็นต้นไป SwingWorker จะถูกรวมอยู่ในJRE [ 1 ]
มีการสร้าง SwingWorker เวอร์ชันที่ไม่เป็นทางการและไม่เข้ากันหลายเวอร์ชันในช่วงปี 1998 ถึง 2006 และต้องระมัดระวังในการหลีกเลี่ยงเอกสารจำนวนมากในเวอร์ชันเหล่านั้นที่ออกมาก่อน Java 6
การใช้งานใน Java 6.0
ปัญหาเธรดการส่งเหตุการณ์
SwingWorker มีประโยชน์เมื่อต้องดำเนินการงานที่ใช้เวลานานหลังจากเหตุการณ์การโต้ตอบของผู้ใช้ (ตัวอย่างเช่น การแยกวิเคราะห์ไฟล์ XML ขนาดใหญ่ เมื่อกดปุ่ม JButton) วิธีที่ตรงไปตรงมาที่สุดในการทำเช่นนั้นคือ:
private Document doc ; ... JButton button = new JButton ( "Open XML" ); button.addActionListener ( new ActionListener ( ) { @Override public void actionPerformed ( ActionEvent e ) { doc = loadXML (); } } ) ;วิธี นี้ใช้ได้ผล แต่โชคร้ายที่ เมธอดนี้จะถูกเรียกใช้ใน เธรดloadXML()เดียวกันกับเธรดหลักของ Swing ( เธรดการส่งเหตุการณ์ ) ดังนั้นหากเมธอดนี้ต้องการเวลาในการทำงานGUIจะหยุดทำงานชั่วคราวในช่วงเวลานั้น
โซลูชัน SwingWorker
ปัญหานี้ไม่ได้จำเพาะเจาะจงกับภาษา Java แต่พบได้ทั่วไปในโมเดลGUISwingWorker หลายๆ แบบ เสนอวิธีแก้ปัญหาโดยการทำงานที่ใช้เวลานานในเธรดพื้นหลังอื่น ทำให้GUIยังคงตอบสนองได้ในระหว่างนั้น
การสร้างคนงาน
โค้ดต่อไปนี้กำหนด SwingWorker ซึ่งห่อหุ้มการloadXML()เรียกใช้เมธอดไว้:
SwingWorker worker = new SwingWorker < Document , Void > () { @Override public Document doInBackground () { Document intDoc = loadXML (); return intDoc ; } };การประหารชีวิตคนงาน
การดำเนินการจะเริ่มต้นโดยใช้ SwingWorker.execute()วิธีการดังกล่าว
กำลังดึงผลลัพธ์
สามารถเรียกดูผลลัพธ์ได้โดยใช้SwingWorker.get()วิธีการดังกล่าว
เนื่องจากการเรียกget()ใช้ Event Dispatch Thread จะบล็อกการประมวลผลเหตุการณ์ทั้งหมด รวมถึงการวาดใหม่ จนกว่างานจะเสร็จสมบูรณ์ ดังนั้นจึงควรหลีกเลี่ยงการเรียกใช้ก่อนที่การดำเนินการที่ใช้เวลานานจะเสร็จสิ้น มีสองวิธีในการดึงผลลัพธ์หลังจากงานเสร็จสมบูรณ์:
- เขียนทับ เมธอดนี้ เมธอดนี้จะถูกเรียกใช้บน เธรดการส่งเหตุการณ์
SwingWorker.done()หลัก
private Document doc ; ... SwingWorker < Document , Void > worker = new SwingWorker < Document , Void > () { @Override public Document doInBackground () { Document intDoc = loadXML (); return intDoc ; } @Override public void done () { try { doc = get ( ); } catch ( InterruptedException ex ) { ex.printStackTrace ( ); } catch ( ExecutionException ex ) { ex.printStackTrace ( ) ; } } }- ลงทะเบียนผู้ฟังโดยใช้
SwingWorker.addPropertyChangeListener(PropertyChangeListener)วิธีการของตัวทำงาน ผู้ฟังจะได้รับการแจ้งเตือนเมื่อสถานะของตัวทำงานเปลี่ยนแปลงไป
ตัวอย่างพนักงานที่สมบูรณ์
private Document doc ; ... JButton button = new JButton ( "Open XML" ); button . addActionListener ( new ActionListener () { @Override public void actionPerformed ( ActionEvent e ) { SwingWorker < Document , Void > worker = new SwingWorker < Document , Void > () {@Override public Document doInBackground () { Document intDoc = loadXML (); return intDoc ; } @Override public void done ( ) { try { doc = get ( ); } catch ( InterruptedException ex ) { ex.printStackTrace ( ); } catch ( ExecutionException ex ) { ex.printStackTrace ( ); } } }; worker.execute ( ); } } );ประวัติการใช้งาน: ใช้งานก่อน Java 6.0
SwingWorker เป็นส่วนหนึ่งของ Java SE ตั้งแต่ Java 6.0 เท่านั้น Sun ได้ออกเวอร์ชันที่ใช้กับ JDK รุ่นก่อนหน้า แม้ว่าจะเป็นเวอร์ชันที่ไม่เป็นทางการซึ่งไม่ได้เป็นส่วนหนึ่งของ Java SE และไม่ได้กล่าวถึงในเอกสารไลบรารีมาตรฐาน[ 2 ]เวอร์ชันล่าสุดเหล่านี้มีอายุตั้งแต่ปี 2003 และมักถูกเรียกว่า SwingWorker เวอร์ชัน 3 [ 3 ]น่าเสียดายที่ SwingWorker ของ JDK 6.0 และ SwingWorker เวอร์ชัน 3 ใช้ชื่อเมธอดที่แตกต่างกันและไม่สามารถใช้งานร่วมกันได้ ปัจจุบันแนะนำให้ใช้เวอร์ชัน backport (ดูด้านล่าง) สำหรับการใช้งานก่อน Java 6
ตัวอย่างการสร้างอินสแตนซ์ของ SwingWorker 3 แสดงไว้ด้านล่าง:
SwingWorker worker = new SwingWorker () { public Object construct () { ... // เพิ่มโค้ดสำหรับเธรดพื้นหลัง} public void finished () { ... // โค้ดที่คุณเพิ่มตรงนี้จะทำงานในเธรด UI } }; worker.start (); // เริ่มเธรดพื้นหลังเมธอด นี้start()จะเรียกใช้โค้ดที่เพิ่มไว้ในเมธอด construct() ในเธรดแยกต่างหาก หากต้องการรับการแจ้งเตือนเมื่อเธรดพื้นหลังทำงานเสร็จสิ้น ก็เพียงแค่เขียนทับfinished()เมธอดนั้น เมธอดนี้construct()สามารถส่งคืนผลลัพธ์ซึ่งสามารถเรียกใช้ได้ในภายหลังโดยใช้get()เมธอด ของ SwingWorker
การพอร์ต SwingWorker จาก Java 6 กลับมาใช้ใหม่
โค้ดเวอร์ชันเก่าของ SwingWorker จาก Java 6 สามารถใช้งานได้กับ Java 5 ที่http://swingworker.java.net/นอกจากชื่อแพ็กเกจแล้ว ( org.jdesktop.swingworker) โค้ดนี้ยังคงใช้งานร่วมกับ SwingWorker จาก Java 6 ได้
ค่าเทียบเท่า
System.ComponentModel.BackgroundWorker- .NET Frameworkflash.system.Worker- Adobe Flashandroid.os.AsyncTask- แอนดรอยด์
ลิงก์ภายนอก
- เอกสารประกอบการใช้งานคลาส SwingWorkerสำหรับ Java 7
- Worker Threads และ SwingWorker จาก บทเรียนJava Concurrency in Swing ของ Oracle
- ปรับปรุงประสิทธิภาพการทำงานของแอปพลิเคชันด้วย SwingWorker ใน Java SE 6โดย John O'Conner มกราคม 2550