Pages

วันจันทร์, เมษายน 11, 2554

Vavar ปะทะ Java Swing #5 : Component Painting

จาก ตอนที่ 4 ที่ได้พูดถึง EDT และ Swing MVC ไปแล้ว

ในตอนที่ 5 นี้เลยจะพูดถึง Painting ครับ

ประกาศ : บทความเหล่านี้เขียนด้วยความคิดเห็นของตัวเองล้วนๆ ... 
ผิดถูกยังไง สามารถเสนอแนะโดย post comment ด้านล่างได้ครับ :)




Swing Component หรือแม้แต่  AWT Component ใน Java นั้นสิ่งที่จำเป็นมากๆ
ในการออกแบบ UI ก็คือการทำ Custom Paint ที่ให้ LookAndFeel  ของตัว Component นั้น
เป็นอย่างที่เราได้ออกแบบไว้ ... โชคร้ายของ AWT Component ที่ ​Java ไม่ได้ออกแบบตรงจุดนี้มาให้
โดยให้เหตุผลว่า AWT เป็น Heavy Weight Class ที่ออกแบบมาให้เป็น Native Component ของ OS นั้นๆ
การจะปรับเปลี่ยน LookAndFeel สำหรับ AWT จึงไม่ใช่ทางออกนัก ....

แต่ก็เป็นโชคดีสำหรับ ​Swing Component ที่ Sun ทำ LookAndFeel Architecture มาให้ใช้
โดยตัว Swing เองอย่างที่เป็น Sequence Diagram ในตอนที่ 4 จะเห็นว่า
JComponent ทั้งหลายเปรียบเสมือน Controller เท่านั้น ส่วนที่เป็น View คือส่วนที่เป็น UI Class
ที่ฝังอยู่ใน LookAndFeel ....

ข้อดีของการแยก Class ดังกล่าวทำให้เราสามารถปรับเปลี่ยนหน้าตาของ UI
โดยไม่กระทบกับ Behavior ที่มีของ Component นั้นๆ ได้ ....
ยกตัวอย่างเช่น

ปุุ่ม .....
หน้าที่ของปุ่มคือรอรับ event การ click โดยจะ click ซ้าย หรือ ขวา ก็ขึ้นอยู่กับ
manage code ที่ทำการตอบรับ action นั้น

แน่นอนว่าหากการเปลี่ยน UI แล้วกระทบกับ Behavior ดังกล่าวดูจะแปลกๆ
ตั้งแต่ลักษณะการ Design ของ Behavior ก่อนหน้านี้แล้ว ....

การ Paint บน Swing Component จึงได้เปลี่ยนการทำงานใหม่ที่แตกต่างไปจาก AWT Component
ที่มีการเรียก paint() method แล้วทำการวาด Component ทั้งหมด

ใน Best Practice ของ Swing Component แนะนำว่าหากต้องการทำ Custom Paint ที่ไม่ขึ้นกับ
LookAndFeel ก็สามารถทำได้โดยการ override paintComponent() (ไม่มี s) method เพื่อให้สามารถ
แสดงผลได้อย่างที่เราต้องการ .....

สิ่งที่สำคัญสำหรับการ paint ใน Swing Component คงจะหนีไม่พ้น 3 สิ่งดังต่อไปนี้

1. Opaque - การแสดงผลแบบ Transparent Background.
2. Border - ขอบของ Component ที่ต้องการให้แสดงผล
3. Inset -  ขอบช่องว่างที่ต้องการให้แสดงผล มักจะถูก set จาก Border

ซึ่งหากเปรียบเทียบกับการเขียน CSS ทั้งสามส่วนนี้คงหนีไม่พ้น คำสั่งดังต่อไปนี้

1. background:
2. border:
3. padding:

จะเห็นได้ว่าจริงๆ แล้ว Component ของ Swing นั้นก็ไม่ได้แตกต่างจาก
การเขียน HTML เท่าไหร่นัก เพียงแต่การใช้งานจะต้องมีการจัด layout
เพื่อให้ได้รูปแบบตามที่เราต้องการ ได้ยากกว่าเท่านั้นเอง ...
แต่โชคร้ายของ Swing Component ที่ Sun ออกแบบมาไม่ดีนัก
ที่ระบุให้ Border เป็น Component ที่ถูกวาดหลังสุด ทำให้การที่เราจะทำ
Component ที่มีขอบ ตามประเภท Border ที่เรา assign ให้กับ Component นั้น ยากมาก
ซึ่งจะต้องหาวิธีมาประยุกต์ใช้เพื่อทำงานในลักษณะดังกล่าว ...

ทำให้มี trick มากมายในการประยุกต์ใช้เพื่อให้ได้รูปแบบตามที่เราต้องการ ....

โดยส่วนตัวคิดว่าไม่ค่อยดีนักสำหรับ การ open ให้ implement เยอะขนาดนี้ เพราะหาก
Developer ไม่สนใจที่จะอ่าน Architect ของ Swing จะทำให้การ ​Manage sourcecode นั้นลำบากมาก
ด้วยอายุของ Swing Toolkit ก็ปาไปเกือบ 10 ปี แล้วจึงคิดว่า javaFX น่าจะมีอะไรเปลี่ยนแปลง
ในจุดนี้ไม่มาก ... ก็น้อย ....

แต่ชีวิตก็ยังต้องดำเนินต่อไป  .... ไปเขียน silverlight ดีกว่า ๕๕๕