Lab 9 : Simple GUI

วัตถุประสงค์
: เพื่อให้นิสิตรู้จัก
Layout ต่างๆ
และสามารถใช้งานร่วมกับ
component ต่างๆ
ได้
โดยใช้การจัดการกับอีเวนต์อย่างง่าย

กราฟิกยูสเซอร์อินเตอร์เฟส
(Graphical User Interface – GUI) คือส่วนของโปรแกรมที่ใช้ติดต่อกับผู้ใช้โปรแกรม
โดยมีจุดประสงค์ของการออกแบบเพื่อให้ใช้งานง่ายโดยอาศัยกราฟิกเข้ามาเป็นส่วนประกอบ
นอกจากนี้ GUI
ยังเป็นตัวบอกรูปร่างหน้าตาของโปรแกรมด้วยว่ามีลักษณะอย่างไร
ใช้งานยากง่ายเพียงใด
กล่าวได้ว่า GUI
เปรียบเสมือนแผนที่ในโปรแกรม
ถ้าให้รายละเอียดดี
ผู้ใช้ก็จะใช้งานได้ง่ายไม่หลงทางในโปรแกรม

Abstract Window Toolkit (AWT)

ภาษา Java
ได้จัดเตรียม
AWT
ไว้ให้เราใช้ในการสร้าง
GUI
ในรูปแบบต่างๆ
ตามต้องการ
โดย AWT
ประกอบด้วย
GUI component มากมายที่ใช้สำหรับสร้าง
GUI ซึ่ง component เหล่านี้สามารถใช้ได้ทั้งใน
Java application และ Java applet

การจะใช้งาน
AWT ได้นั้น
เราจะต้องอิมพอร์ตแพ็กเกจ
java.awt
เข้าไว้ในโปรแกรมด้วย
เนื่องจาก GUI
component ต่างๆ
ที่สร้างขึ้นจะเป็นคลาสที่สืบทอดคุณสมบัติมาจาก
(เป็นคลาสลูกของ)
คลาส Component หรือคลาส
MenuComponent
คลาสใดคลาสหนึ่งในแพ็กเกจดังกล่าวเสมอ

Container
คือ
ส่วนที่ใช้สำหรับวาง
GUI component ต่างๆ
ซึ่งเราสามารถวาง
GUI component ลงใน Container
ได้โดยเรียกใช้เมธอด
add ของ Container (คลาส
Container)

Swing

Swing
ประกอบด้วย
GUI component จำนวนมากที่ใช้สำหรับสร้าง
GUI เช่นเดียวกับ
AWT โดย component ต่างๆ
ของ Swing (Swing component)
จะเป็นคลาสที่สืบทอดคุณสมบัติมาจากคลาส
JComponent ในแพ็กเกจ
javax.swing (ซึ่งคลาส
JComponent สืบทอดคุณสมบัติมาจากคลาส
Container
ในแพ็กเกจ java.awt
อีกทีหนึ่ง)
ดังนั้นในการใช้งาน
Swing เราจะต้องอิมพอร์ตคลาสต่างๆ
ในแพ็กเกจ javax.swing เข้าไว้ในโปรแกรมด้วย

ชื่อคลาสที่เป็น
Swing component จะนำหน้าด้วยตัวอักษร
J ยกตัวอย่างเช่น
JLabel, JButton, JTextField เป็นต้น

AWT ใช้สร้าง
GUI ได้อยู่แล้ว...ทำไมต้องมี
Swing อีก?

เหตุผลที่มีการสร้าง
Swing
ขึ้นมาสำหรับใช้ในการสร้าง
GUI อีก เพราะ AWT
มีข้อเสียตรงที่
GUI ที่สร้างขึ้นจะมีรูปร่างหน้าตาไม่ค่อยเหมือนกันเมื่อนำไปรันบนระบบปฏิบัติการที่แตกต่างกัน
ซึ่งบางครั้งรุนแรงถึงขั้นแสดงผลผิดเพี้ยนไปเลยก็มี

กล่าวคือ
เมื่อนำโปรแกรมที่สร้าง
GUI ด้วย AWT ไปรันบน
Windows จะได้หน้าตาออกมาแบบหนึ่ง
แต่เมื่อนำไปรันบน
Linux ก็อาจได้หน้าตาออกมาอีกแบบหนึ่ง
เรียกได้ว่า AWT
ยังคงทำงานโดยยึดติดหรือขึ้นกับ
platform อยู่
ด้วยเหตุผลนี้เองที่ทำให้มีการสร้าง
Swing ขึ้น
ซึ่งเมื่อสร้าง
GUI โดยใช้ Swing
component แล้ว
ไม่ว่าจะนำไปรันบนระบบปฏิบัติการใดก็จะได้หน้าตาออกมาเหมือนกัน

อีกเหตุผลหนึ่งที่
Swing ถูกสร้างขึ้นเพราะ
GUI component ของ AWT
ยังมีความสามารถไม่เพียงพอ
คือมันสามารถติดต่อกับผู้ใช้งานโปรแกรมได้ในระดับง่ายๆเท่านั้น
ไม่สามารถใช้กับงานที่มีความซับซ้อนได้
ดังนั้น Swing จึงถูกสร้างขึ้นให้มี
component ต่างๆ
ที่มีความสามารถมากขึ้นกว่า
GUI component ของ AWT

Swing
ประกอบด้วย
component หลักๆ 2 ประเภท คือ top-level
container และ lightweight component

Top-level
container ประกอบด้วย
component 4 ตัว คือ JFrame, JApplet, JWindow และ JDialog

Lightweight
component เป็น component อื่นๆของ Swing ที่ไม่ใช่ top-level
container

โดยปกติ
top-level container
ถูกสร้างขึ้นเพื่อใช้สำหรับวาง
lightweight component
ลงไปบนตัวมัน
อย่างไรก็ตาม
เราไม่สามารถวาง
component ของ Swing ลงไปบน
top-level container
ได้โดยตรง
แต่จะต้องวาง
component เหล่านี้ผ่านทาง
content pane (object
ของคลาส Container) ภายใน top-level container อีกทีหนึ่ง
ซึ่งเราสามารถเข้าถึง
content pane ภายใน top-level
container หนึ่งๆ
ได้โดยเรียกใช้เมธอด
getContentPane
ของ top-level container นั้น

สรุปประเด็นสั้นๆ
นะครับดังนี้

AWT เป็น toolkit ที่คุยกับ controls
ที่ระบบปฏิบัติการเบื้องล่างสนับสนุนโดยตรง
เลยถูกเรียกว่า
heavyweight component เพราะ
1 ปุ่มที่สร้างขึ้น
เป็น 1 ปุ่มที่เกิดจากการไปสร้าง
control ปุ่มของระบบปฏิบัติการจริงๆ

ปัญหาของ
AWT จริงๆ
คือจาวาพยายามจะ
Write Once Run anywhere จะมีปัญหาได้เพราะบางฟีเจอร์
Platform ข้างล่างของ
system ไม่สนับสนุนหรือสนับสนุนไม่เหมือนกัน
กลายเป็นว่าไปพึ่งพิงกับ
control ของ platform หนึ่งๆ
มากเกินไปจะเสีย
concept เอา พอ port
ไปลงอีก platform
ก็ทำงานไม่ได้
หรือได้แบบไม่ดีนัก และก็ code หรือ
gui ที่แตกต่างกันไปในแต่ละ
Platform จะส่งผลให้การ
maintain มากขึ้น

Swing ทำงานครอบอยู่บน
AWT อีกทีนึง
โดยทำหน้าที่เป็น
gui toolkit ที่เสริมความสามารถให้ทุกอย่างเป็นไปได้โดยไม่ต้องสนใจ
Platform ข้างล่างอย่างแท้จริง
โดย swing component จะอาศัยการ
"วาด" เอา

ปุ่มแต่ละปุ่มที่
swing วาด
เกิดจาก java วาดไม่ใช่ระบบปฏิบัติการสร้าง
จะเห็นได้ว่า
swing เลยปรับ
look & feel ได้อย่างอิสระ
สร้าง Look & feel ที่ขยายหรืออยู่นอก
control ที่ระบบปฏิบัติการมีให้ก็ได้

ทีนี้ก็มาถึงสิ่งที่นิสิตจะต้องทำกันล่ะครับ

1)  Lab Menus ให้นิสิตเขียนเมนูหลักสำหรับข้อย่อยๆที่มีในนั้น
3 ข้อครับ
ตามรูป

เงื่อนไขของเมนูนี้นะครับ

1.     กำหนด size กว้าง
200 pixel สูง 130 pixel
ส่วน x, y จะไว้ตรงไหนของจอก็ได้ครับ
และไม่ให้สามารถเปลี่ยน
size ได้
คือยืดหดขนาดของหน้าต่างไม่ได้ครับ

2.     เมื่อกดปุ่มปิด
(x) ที่มุมบนขวาหมายความว่าปิดโปรแกรมนี้ครับ
คำสั่งที่ใช้คือ
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

3.       button ที่ใช้
กำหนดให้ใช้ JButton ครับ

4.       จะใช้ layout ใดๆก็ได้ครับ
แนะนำว่าใช้ FlowLayout จะง่ายดีครับ

5.       การดักจับ
event
ของปุ่มจะใช้คำสั่ง

buttonInstant.addActionListener(new
ActionListener(){

public void actionPerformed(ActionEvent e) {

//do something;

}

});

6.     ถ้ากด button
ของข้อย่อยข้อใดข้อหนึ่งจะปรากฏหน้าต่างใหม่ขึ้นมา
และสามารถปรากฏได้พร้อมกันกี่หน้าต่างก็ได้ครับ
แต่ถ้ากดปิด  (x) ที่มุมบนขวา
ของหน้าต่างข้อย่อยๆ
จะไม่มีผลให้ปิดโปรแกรม
Lab Menu
หลักนี้นะครับ
เช่นดังรูป

2) Train
Layout1 มี size เริ่มต้น
คือ กว้าง 300 pixel สูง 300 pixel ใช้
Card Layout เป็น panel
หลักเนื่องจากสามารถซ้อน
panel
ต่างๆได้
เวลาเปลี่ยน panel
สามารถเปลี่ยนได้โดยใช้
dropdown list ด้านล่างของ
panel แล้วเลือก
layout ที่ต้องการ
ดังรูป

โดยมี 3 panel
ย่อยที่ใช้
Layout ดังนี้

1.       Border
Layout  กำหนดให้มีหน้าตาดังรูป

2.       Box
Layout กำหนดให้มีหน้าตาดังรูป

3.       Flow
Layout กำหนดให้มีหน้าตาดังรูป

3)
TrainLayout2 ไม่กำหนด
size ให้ใช้คำสั่ง
pack แทน
และใช้ JTabbedPane
โดยประกอบด้วย
2 panel ที่เป็น layout
ย่อยคือ

1.
Grid Layout กำหนดให้มีหน้าตาดังรูป

2.
GridBag Layout เป็น
button
ที่ประกอบกันเป็นรูป
robot
ที่สวยงามดังรูป

โดยซ้ายขวาบนล่างมีความสมมาตรกันหมดและมีความสูงและความกว้างของ
robot ดังนี้
(หน่วยเป็น pixel)

จากรูปด้านบนมีบางส่วนที่ไม่ได้กำหนด
pixel
ไว้ให้นิสิตประมาณเอาเอง
(เท่าไหร่ก็ได้แต่ให้ภาพดูคล้ายมากที่สุด)
ส่วนระยะห่างระหว่างกรอบกับหุ่นยนต์ให้นิสิตเหลือพื้นที่ไว้เล็กน้อยเท่าไหร่ก็ได้ครับแต่มากกว่า
0 pixel

สิ่งที่ควรจะมีในการสร้าง

·
สร้าง
GridBagConstraints
เพื่อให้มี
constraint instance ทำให้สามารถที่จะ
set ค่า gridx,
gridy, ipadx, ipady, inserts, gridwidth, gridheight, fill ได้

·
gridx, gridy : บอกตำแหน่งของ
column, row
ตามลำดับ

·
ipadx, ipady : เป็นความกว้างและความยาวของ
component

·

component

c

b

d

a

inserts
: เป็นการเพิ่มขนาดของ
cell นั้นๆ
โดยให้ค่าดังนี้  new Insets(a, b, c,
d)

·
gridwidth, gridheight : บอกจำนวนของช่องตามความแนว
column, row

·
fill : บอกลักษณะการวางของ
component เช่น GridBagConstraints.HORIZONTAL

·
เมื่อกำหนด
constraint เสร็จแล้วก็อย่าลืม
set constraint ให้กับตัว
gridBagLayout instance

·
แนะนำว่าควรจะตีตารางเป็น
grid
ในกระดาษก่อนเพื่อง่ายต่อการเขียนโปรแกรม

3)
Mini Notepad!

มีข้อกำหนดดังนี้

1.
มีขนาดเริ่มต้นคือ
600 * 600 pixels

2.
component ที่ใช้หลักๆ
คือ

javax.swing.ImageIcon;

javax.swing.JFileChooser;

javax.swing.JFrame;

javax.swing.JMenu;

javax.swing.JMenuBar;

javax.swing.JMenuItem;

javax.swing.JOptionPane;

javax.swing.JScrollPane;

javax.swing.JTextArea;

3.
รูปใช้รูปดังนี้
(save
ไปใช้ได้เลย
หรือจะเอาจาก
link นี้ก็ได้)

4.
เมื่อกด
file ที่ menu bar
จะเป็นดังรูป

5.
ถ้ากด
New หรือเริ่มแรกที่เปิดโปรแกรมให้เขียนว่า
Mini Notepad!: Untitled ที่ Title
Bar

6.
ถ้าเอา
mouse ไปวางไว้ที่
New ให้ show tool tip ว่า “New Text File” ด้วย
ดังรูป

7.
เมื่อกด
Open ให้เป็นดังรูป

8.     กำหนดให้เปิดไฟล์ที่มีนามสกุลเป็น
.txt
ได้อย่างเดียวเท่านั้น
หากไปเลือกไฟล์นามสกุลอื่นให้แจ้ง
Message Dialog ว่า “<file
name> is not .txt extension!” ตามรูป

9.       เมื่อเปิด
text file แล้ว
ให้มีข้อความขึ้นมาแสดงที่
JTextArea
เหมือนกับที่
text file
ที่เปิดมี

10.    ที่ Title Bar ให้เป็นชื่อ
Mini Notepad!: <file name>

11.   ถ้า
ไฟล์ที่เปิดมีนามสกุลเป็น
.txt
แต่ไม่มีอยู่จริง
ให้แจ้งเตือนด้วย
Message Dialog ว่า “<file
name> does not exist!” และไม่มีการกระทำใดๆ
กับ JTextArea
และ Title Bar

12.    เมื่อกด Save As ให้เป็นดังรูป

13.   กำหนดให้บันทึกไฟล์ที่มีนามสกุลเป็น
.txt
ได้อย่างเดียวเท่านั้น
หากไปเลือกไฟล์นามสกุลอื่นหรือพิมพ์ไฟล์ผิดนามสกุลให้แจ้ง
Message Dialog ว่า “<file
name> is not .txt extension!” ตามรูป

14.    การบันทึกต้องมีตัวหนังสือเว้นบรรทัดเหมือนกัน
โดยให้บันทึกด้วย
‘\r\n’ ในการเว้น
1 บรรทัด

15.    เมื่อบันทึกแล้วที่
Title Bar ต้องเปลี่ยนข้อความเป็น
Mini Notepad!: <file name ที่บันทึก>

ข้อแนะนำ

1.       การอ่านเขียนไฟล์
ใช้ BufferedReader, BufferedWriter

2.       การโชว์ Message Dialog ใช้ JOptionPane.showMessageDialog…

3.       การนำภาพไอคอนมาใส่ใน
MenuItem ใช้ new
JMenuItem("Open...", new ImageIcon("Open.gif"));

4.       showOpenDialog, showSaveDialog เป็นเมธอดสำหรับแสดง
Dialog ของ JFileChooser
Instance

5.     เวลาที่เลือก
Open หรือ Save ถ้า Dialog
ขึ้นมาแล้วไปกดที่
ปุ่มด้านซ้ายที่ไม่ใช่
Cancel จะมีค่า
Return Value มาให้เป็น
JFileChooser.APPROVE_OPTION

6.       การ show tool tip ใช้คำสั่ง menuItemInstance.setToolTipText(…

การส่ง

ให้ export เป็น
Jar file
แล้วส่งมาที่
[email-masked] ภายในวันอาทิตย์ที่
26 สิงหาคม 2550
เวลา 24.00 น.
ไฟล์จะต้องตั้งชื่อว่า
lab09_xxxxxxxxxx.jar โดย xxxxxxxxxx นั้นเป็นเลขประจำตัวนิสิต
ส่วนใน subject ของเมล์
ให้ใส่ lab09_ xxxxxxxxxx_Time
โดย xxxxxxxxxx
นั้นเป็นเลขประจำตัวนิสิต
และ Time เป็นเวลา
(หน่วยเป็นชั่วโมง:นาที)
ที่นิสิตใช้ในการทำแล็บนี้