Lab05: ดัดแปลง Game of Life
เราต้องการเอาตารางแบบที่ทำในแล็บที่แล้ว มาใช้ทำโฆษณาไฟวิ่ง (โอเค มีแค่สีขาวกับดำก็พอ ไม่ต้องเพิ่มสี)
ตอนที่ 1 จัดการแบคทีเรียให้วิ่งต่อเนื่อง ให้เป็นก่อน
จากคราวที่แล้ว จะเห็นว่า เราทำแบคทีเรียให้วิ่งเป็น Step ไป ทีละขั้น แ่ต่คราวนี้เปลี่ยนใหม่
- เพิ่มปุ่มหนึ่งปุ่ม เขียนว่า Run
- เมื่อกดปุ่มนี้แล้ว ชื่อปุ่มจะเปลี่ยนเป็นชื่อ Stop
- แล้วตัวแบคทีเรียก็จะเคลื่อนไหวตาม Step ไปเรื่อยๆ จนกว่าผู้ใช้งานจะกดที่ Stop ถึงจะหยุด
ทำเล้ย แล้วเซฟจาร์ไฟล์ที่ execute ได้ไว้นะ ตั้งชื่อว่า studentId_lab05-01_secNumber.jar
ไกด์
โอเค
ก่อนอื่นเราลองใช้ลูปดู จะสังเกตว่า โปรแกรมปุ่มถูกกดค้างไว้แล้วหยุดไปเลย
ทั้งนี้เพราะว่า ปุ่มจะไม่เด้งคืนจนกว่าการคำนวณที่บอกให้ปุ่มไปทำ จะเสร็จ
แต่ว่า ถ้าเป็นแบบนี้จะไม่มีวันเสร็จ เพราะว่าปุ่มไม่เด้งมาให้กด Stop ไงโปรแกรม พอปุ่มไม่เด้ง ก็จะแฮ้ง ทันที
ดังนั้นเราจึงต้องใช้วิธี
ให้ปุ่มไม่รอการคำนวณ โดยบอกจาวา ให้ไปรันโค้ดของปุ่มต่างหาก
(เปรียบเหมือน สร้าง main ขึ้นมาอีกอัน แล้วบอกให้โค้ดส่วนที่รันตอนกดปุ่ม
ไปรันใน main ที่รันต่างหากนั้น)
ซึ่ง main ที่รันต่างหากนั้น
เราเรียกว่า เป็นอีก thread หนึ่ง (ตัว main เอง ก็ถือเป็น thread หนึ่ง
thread) ดังนั้น thread ก็ถือเป็นโค้ดที่รันได้พร้อมๆกันนั่นเอง
วิธีทำ
ผมจะสอนไปด้วยเลยก็แล้วกัน ก่อนอื่น สมมุติว่าเราจะเขียนโค้ดทั้งหมดใน
listener ที่เราเขียนคลาสขึ้นมาเองสำหรับปุ่มใหม่นี้ เมธอดที่จะรันใน
thread ใหม่ จะต้องมีชื่อว่า public void run()
ซึ่งก่อนอื่นต้องบอกคลาสของตัว listener นี้ก่อน ว่า
"เจ้าเป็นพวกเดียวกับสิ่งที่สามารถสั่ง thread อีกตัวรันต่างหากได้นะ"
ซึ่งการบอกว่าเป็นพวกเดียวกัน นี้ ใช้ implements Runnable ->
"เจ้าเป็นพวกเดียวกับ Runnable นะ"
ซึ่ง Runnable นั้น
จาว่ารู้จัก ว่า ใครที่เป็นพวกเดียวกับ Runnable จะสามารถสร้าง thread
อีกตัวแยกต่างหากจาก main ได้ และ thread นี้จะรันโค้ดของ เมธอด run
ซึ่งจะต้องเตรียมไว้นั่นเอง
- คอนสตรัคเตอร์
- เซ็ตค่าเริ่มต้นของทุกอย่าง จากนั้นสร้าง thread ขึ้นมา สั่งรัน
- โค้ดของ actionPerformed จะ
- เซ็ตให้ boolean เป็น true หรือ false boolean นี้จะใช้บอกว่า จะทำอะไรบ้างตอน run()
- เมธอด run()
- มีโค้ดทั้งหมดในการลูป ทำ step ต่างๆของแบคทีเรีย
โครงของโค้ดสำหรับปุ่มใหม่ เป็นดังนี้
public
class stopButtonListener extends stepButtonListener implements
ActionListener, Runnable { //extends
เพื่อให้ใช้เมธอดทั้งหมดได้แบบเดียวกับ stepButtonListener เลย เพื่อจะให้
step ได้
// implements Runnable ตรงนี้ด้วย
เพื่อบอกจาว่า ว่า จะมี thread อีกตัวที่นิยามในคลาสนี้
JButton temp;
boolean running;
public stopButtonListener(..........) {
.............................................
...........................................
Thread x = new Thread(this); // สร้าง thread ขึ้นมา
thread นี้ยังไม่รัน เมธอด run ของ thread นี้ จะถูกนิยามใน this ซึ่งในที่นี้ก็คือ คลาสที่เรากำลังเขียนโปรแกรมอยู่นี่เอง
x.start(); // สั่ง thread ให้รันเมธอด
run() แต่คำสั่งนี้ นอกจากสั่งให้ run() แล้ว ยังบอกจาว่า ด้วย ว่า เฮ้ย
ต้องรันเหมือนเป็นอีกโปรแกรมแยกต่างหากกันจาก main
}
public void run() { // เป็นเมธอดที่เราจะใช้รัน แยกต่างหากจาก main
เมธอดนี้ต้องมีชื่อนี้เสมอ เพราะถูกบังคับมาจาก Runnable
ที่เราบอกว่าคลาสนี้ เป็นพวกเดียวกับ Runnable ด้านบน
while (true) {
if (running = = true) {
try {
Thread.sleep(100); //บอกให้
หน่วงเวลาการทำลูปไว้ 100 มิลลิวินาที
ทั้งนี้เพื่อให้การแสดงผลไม่เร็วเกินไป เดี๋ยวมองตามไม่ทัน
.......................
..........................
} catch (InterruptedException e) {
}
} else {
try {
.....................................
} catch (InterruptedException e) {
}
}
}
}
public void actionPerformed(ActionEvent e) {
temp = (JButton) e.getSource();
if (temp.getText().equals("Run")) {
temp.setText("Stop");
running = true;
} else {
temp.setText("Run");
running = false;
}
}
ตอนที่ 2 ทำไฟโฆษณาวิ่งไปทางซ้ายของจอ แล้วพอส่วนไหนลับจอ ก็ให้โผล่มาทางริมขวาของจอใหม่
เอาโปรเจ็กต์แบคทีเรียมาขึ้นเป็นโปรเจ็กต์ใหม่ สำหรับอันนี้ ต้องเขียนเพิ่ม โดย
- เอาปุ่ม Random ทิ้งไป
- ปุ่ม Step ให้ทำการเลื่อนช่องสีดำไปหนึ่งช่องทางซ้าย แทนการกระทำเดิม
- ปุ่มรัน ให้รัน Step ต่อเนื่องไปเรื่อยๆ (พอกดแล้วจะกลายเป็น Stop) จนกว่าจะกด Stop
- ปุ่ม clear ทำงานเหมือนเดิม คือเคลียร์หน้าจอทั้งหมด
เซฟ executable จาร์ไฟล์ไว้แยกต่างหากจากตอนที่ 1 ตั้งชื่อว่า studentId_lab05-02_secNumber.jar
ตอนที่ 3 ไฟโฆษณา ต่อเนื่อง เปลี่ยนจากข้อความหนึ่งเป็นอีกข้อความหนึ่ง
เอาตอนที่สอง มาเปิดเป็นโปรเจ็กต์ใหม่ โดย
- เริ่มต้นมา โปรแกรมจะมีวินโดว์ pop upให้เราใส่ว่า จะใช้ข้อความต่อเนื่องกี่ข้อความ
- พอเลือกแล้ว
หน้าต่างวินโดว์ที่เป็นช่องๆแบบในตอนที่ 2 ก็จะปรากฏ โดยคราวนี้จะมีแผง
JComboBox (ดูตัวอย่างเพิ่มใน slide GUI ที่อยู่บนเว็บ)
ปรากฏอยู่ด้วยด้านล่างปุ่มคอนโทรลทั้งหลาย ซึ่งในนั้นจะมีให้เราเลือก
ว่าเราอยู่ที่ข้อความที่เท่าไร พอเลือก choice ไหน
หน้าจอก็จะเปลี่ยนเป็นข้อความที่เราเคยบันทึกไว้ของ choice นั้น
หรือถ้าไม่เคยบันทึกไว้ จอก็จะว่างไง
- มีปุ่ม Record ให้เราบันทึกหน้าจอไว้ ซึ่งหน้าจอจะถูกบันทึกไว้ในฐานะข้อความใดนั้น JComboBox จะเป็นตัวบอก
- ปุ่ม Run (พอกดแล้วจะกลายเป็น Stop) ทำการรันป้ายโฆษณา โดยเริ่มจาก
- โชว์ข้อความที่หนึ่งบนจอ
- แหกข้อความออกตรงกลางจอ ด้านที่อยู่ใกล้ริมหน้าจอซ้ายให้ตัวหนังสือเลื่อนไปทางซ้าย ด้านที่อยู่ใกล้ริมหน้าจอขวาให้ตัวหนังสือเลื่อนไปทางขวา
- พอเลื่อนจนลับจอไปหมดแน่แล้ว ข้อความต่อไปจะเลื่อนเข้ามาแทนที่ โดยเลื่อนมาจากคนละข้างของจอเหมือนกัน
- พอมาบรรจบกันเรียบร้อย ก็จะค้างไว้นิดนึง แล้วเริ่มแหกข้อความออกอีก เพื่อเอาข้อความใหม่เข้ามา ทำอย่างนี้ต่อไปเรื่อยๆ
- ไม่หยุดจนกว่าจะกด Stop
- ปุ่ม Step ใช้เอาไว้ test ปุ่ม Run เป็นขั้นๆ
- ปุ่ม clear ทำงานเหมือนเดิม แต่คราวนี้ เคลียร์เฉพาะข้อความที่ถูกเลือกอยู่ ณ ตอนนั้นเท่านั้น (ดูจาก JComboBox)
เซฟ executable จาร์ไฟล์ไว้แยกต่างหากจากตอนที่ 2 ตั้งชื่อว่า studentId_lab05-03_secNumber.jar
zip 3 ไฟล์เข้าด้วยกัน ส่งมาที่ progmethcp@gmail.com ภายในเที่ยงคืนวันอาทิตย์ (ใช่แล้ว คราวนี้แล็บถือเป็นการบ้านในตัวอีกแล้ว) โดยในเมล์ subject ต้องเขียนเป็น studentId_lab05_secNumber และชื่อไฟล์จะต้องเป็น studentId_lab05_secNumber.zip ตัวอย่างเช่น 5032117621_lab05_1.zip
studentID คือเลขประจำตัวนิสิต
secNumber คือเบอร์ตอนเรียน