Giáo trình Java

Phâ n VI: T¹o ra mét GUI víi JFC/Swing

TÓM T T Trong ph n này s h ng d n b n cách t o ra nh ng giao di n ng i dùng ho (GUIs) v i JFC/Swing cho nh ng ng d ng và applets thông qua vi c s d ng nh ng thành ph n Swing . Nh ng thành ph n Swing, m t b ph n c a Java TM Foundation Classes (JFC), có th c s d ng ho c v i JDK TM 1.1 ho c JavaTM 2 platform. Ghi chú: ph n này không h ng d n b n cách s d ng nh ng thành ph n AWT
1. Nh p môn v i S wing Trong phÇn nµy sÏ l-ít qua nhanh vµ nh»m môc ®Ých lµ cho b¹n h×nh dung vÒ JFC vµ Swing. Sau ®ã sÏ lµ c¸ch ®Ó biªn dÞch vµ ch¹y ch-¬ng tr×nh - cho c¶ øng dông vµ c¸c applets th«ng qua viÖc sö dông c¸c thµnh phÇn Swing b»ng mét ch-¬ng tr×nh ®¬n gi¶n.

2. Các khái ni m và ch c n ng c a Swing Cung c p các thông tin c n thi t s d ng các thành ph n Swing m t cách có hi u qu . Ví d nh cách m t ch ng trình Swing hi n th giao di n ho ng i dùng, cách qu n lý các s ki n nh kích chu t và cu i cùng s là vi c s d ng các khái ni m và ch c n ng nh th nào trong m t ch ng trình th c s . 3. S d ng các thành ph n Swing H ng d n cách s d ng m i thành ph n Swing ± button, table, các thành ph n text«(nhìn chung các thành ph n Swing cung t ng t nh các thành ph n AWT . Tuy nhiên, chúng có m t s tính n ng m i. Ví d nh button, label có th n p hình nh,...) 4. S d ng các ch c n ng khác c a Swing . Nói thêm v các thành ph n khác c a Swing nh actions, borders, icons, và timers. Ngoài ra s còn h ng d n b n cách t o m t ch ng trình a tuy n (multithreaded) 5. Các thành ph n Laying Out là it ng ch a .

H ng d n cách ch n m t (layout manager), cách s d ng c a m i l p layout manager mà Java cung c p. 6. Cách vi t m t s ki n Listener H ng d n cách n m b t các s ki n trong ch h a ng v , các text i thành Swing
1

ng trình

7. Làm vi c v i S d ng các ng. 8. Chuy n

ch t o ra m t hình nh, k c các hình nh

35559403.doc

Giáo trình Java

H ng d n cách chuy n i m t ch ng trình s d ng AWT API 1.1 sang ch trình s d ng các thành ph n Swing .

ng

Bài 1: B t
1.

u v i Swing

ôi i u v JFC và Swing

JFC (Java Foundation Classes) là m t t p h p các ch c n ng giúp ng i dùng xây d ng giao di n ho (GUIs). JFC c công b l n u tiên vào n m 1997 trong h i ngh v nh ng nhà phát tri n JavaOne , bao g m nh ng ch c n ng sau: 1. Các thành ph n Swing 2. H tr Pluggable Look and Feel 3. Truy c p API 4. Java 2D API (Java 2 Platform only) 5. H tr Drag and Drop (Java 2 Platform only) 3 ch c n ng u c a JFC c th c hi n mà không c n b ng mã qu c gia mà d a vào các hàm API có trong JDK 1.1
Nh ng phiên b n có Swing API

Swing API ã c s d ng trong 2 d ng sau: (1) Là ph n c t lõi c a Java 2 Platform (phiên b n chu n c a v 1.2 và v 1.3) (2) JFC 1.1 (s d ng v i JDK 1.1) V i m i phiên b n s d ng, tùy thu c vào vi c chúng ta c n n JDK 1.1 hay là Java 2 Platform và không c n ph i thêm b t k th vi n nào mà v n có th s d ng c Swing API. Tuy nhiên, n u c n s d ng JDK 1.1 thì thêm vào Swing API (s d ng JFC 1.1) Hãng Sun ã phát hành nhi u phiên b n c a JFC 1.1 và nh n bi t nó là phiên b n nào thì c n d a vào phiên b n c a Swing API ch a trong nó . B ng sau ây li t kê các thông tin v Swing API.
Swing Version API T ng ng v i T ng ng v i phiên b n phiên b n Chú thích Java 2 Platform JFC 1.1 (Standard Edition) JFC 1.1 Phiên b n c a JFC 1.1 bao g m Java PlugKhông (with inTM 1.1.1. Swing 1.0.3) Phiên b n u tiên có y Swing 1.1 API h tr s d ng các s n ph m th ng m i. Java Plug-in 1.1.2 và Java Plug-in 1.2 JFC 1.1 v 1.2, v 1.2.1 (with Swing 1.1) cung c p applet h tr cho t ng JDK 1.1 + Swing 1.1 và Java 2 Platform v 1.2 t ng ng. Thêm vào các tính n ng m r ng, x lý v 1.2.2 JFC 1.1 nhi u l i k thu t, các ch c n ng m i (API

Swing 1.0.3

Swing 1.1

Swing 1.1.1
35559403.doc

2

Giáo trình Java

(with Swing 1.1.1)

Không có s khác bi t v Không có "Swing" version

v 1.3 Beta

không c n thay i) cho Swing 1.1. Java Plug-in 1.1.3 và Java Plug-in 1.2.2 cung c p applet h tr choJDK 1.1 + Swing 1.1.1 và Java 2 Platform v 1.2.2, t ng ng. Thêm vào các tính n ng, x lý nhi u l i k thu t, các ch c n ng m i. B sung thêm các tính n ng và các hàm API m i. Java Plug-in 1.3 Beta cung c p applet h tr cho phiên b n này.

Các gói Swing

Swing API v a l n m nh, l i v a m m d o. Trong phiên b n 1.1 c a API có 15 gói dùng chung: javax.accessibility , javax.swing, javax.swing.border, javax.swing.colorchooser , javax.swing.event, javax.swing.filechooser, javax.swing.plaf, javax.swing.plaf.basic, javax.swing.plaf.metal, javax.swing.plaf.multi , javax.swing.table, javax.swing.text, javax.swing.text.html , javax.swing.tree, and javax.swing.undo. Trong h u h t các ch ng trình ch s d ng m t ph n nh c a API , ch y u là các gói Swing javax.swing, javax.swing.event.
S khác biêt gi a các thành ph n Swing và AWT

Các thành ph n AWT c cung c p trong JDK 1.0 và 1.1. M c dù Java 2 Platform v n còn h tr các thành ph n AWT, tuy nhiên, chúng ta nên dùng các thành ph n Swing. Khi s d ng, có th phân bi t các thành ph n Swing v i các thành ph n AWT. Các thành ph n Swing có tên b t u b ng ký t J . Ví d nh , l p AWT button class có tên là Button thì l p Swing button có tên là Jbutton. Ngoài ra, các thành ph n AWT thì n m trong gói java.awt, còn các thành ph n Swing thì n m trong gói javax.swing. Do ó, khi s d ng các thành ph n Swing thì trong ph n khai báo c a ch ng trình , ta nh thêm vào dòng l nh sau : import javax.swing.*; S khác bi t l n nh t gi a các thành ph n AWT và Swing y là các thành ph n Swing c th c thi mà hoàn toàn không c n mã ngu n (with absolutely no native code). K t khi các thành ph n Swing không còn b h n ch trong nh ng khuôn m u thông th ng, (the least common denominator), t c là lúc mà các tính n ng c a nó ã có m t h u h t trong các phiên b n, thì các ch c n ng c a nó ã m r ng h n nhi u so v i các ch c n ng c a các thành ph n AWT. Do các thành ph n Swing không có mã ngu n (native code), nên chúng có th c thêm vào nh là m t add -on c a JDK 1.1 hay nh m t ph n c a Java 2 Platform. Ngay c nh ng thành ph n Swing các thành ph n AWT:
y y

n gi n nh t c ng ã có nh ng kh n ng v

t xa

Swing buttons và labels có th hi n th hình nh và c v n b n . Có th d dàng thay i th d dàng thay i ó. ng vi n c a h u h t các thành ph n Swing. Ta có ng vi n c a m t label hay m t i t ng ch a nào

35559403.doc

3

Giáo trình Java y

Có th d dàng thay i hành vi hay giao di n c a m t thành ph n Swing trong ph ng th c i u khi n c a nó ho c t o ra m t l p con (subclass) c a chính thành ph n ó. Thành ph n Swing không có hình ch nh t . Do ó, các nút l nh có th có hình tròn ho c bo góc. K thu t h tr (Assistive technologies) qua vi c l y thông tin t các thành ph n Swing .
ng trình Swing

y

y

c màn hình có th d dàng

2. Biên d ch và th c thi m t ch

Ð vi t m t ch ng trình s d ng các thành ph n Swing , tr c tiên, ta ph i có phiên b n c a JDK và JFC t ng ng. Biên d ch và th c thi m t ch ng trình Swing còn tùy thu c vào vi c ang s d ng JDK 1.1 hay Java 2 Platform. N u s d ng Java 2 Platform thì s n gi n h n vì Swing ã c tích h p . 2.1 Biên d ch và th c thi ch ng trình v i Java 2 Platform, v 1.2 or 1.3 qua ví d SwingApplication.java có

Trong ph n này, chúng ta s kh o sát các v n giao di n nh sau:

Sau ây là các b c trình t cho vi c biên d ch và th c thi m t ch v i Java 2 SDK, v 1.2 hay v 1.3: 1. N u ch a có, cài 2. T o m t ch 3. Biên d ch ch t vào máy phiên b n Java 2 Platform.

ng trình Swing

ng trình s d ng các thành ph n Swing . ng trình. ng trình.

4. Cho th c thi ch

Hi n nay, ang có 2 phiên b n c a Java 2 Platform, t t c u mi n phí do Sun cung c p (b n có th vào a ch này c h tr : http://www.sun.com). Phiên b n th nh t là v 1.2 (Java 2 SDK, Standard Edition v 1.2) và phiên b n th hai là v 1.3 (Java 2 SDK, Standard Edition v 1.3). Ð t o m t ch ng trình s d ng các thành ph n Swing , có th s d ng ch ng trình m u mà chúng tôi cung c p sau ây SwingApplication.java. C n l u ý là tên file ph i chính xác là: "SwingApplication.java" import javax.swing.*; //This is the final package name. //import com.sun.java.swing.*; //Used by JDK 1.2 Beta 4 and all //Swing releases before Swing 1.1 Beta 3. import java.awt.*; import java.awt.event.*;
35559403.doc

4

Giáo trình Java

public class SwingApplication { private static String labelPrefix = "Number of button clicks: "; private int numClicks = 0; public Component createComponents() { final JLabel label = new JLabel(labelPrefix + "0 ");

JButton button = new JButton("I'm a Swing button!"); button.setMnemonic(KeyEvent.VK_I); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { numClicks++; label.setText(labelPrefix + numClicks); } }); label.setLabelFor(button); /* * An easy way to put space between a top -level container * and its contents is to put the contents in a JPanel * that has an "empty" border. */ JPanel pane = new JPanel(); pane.setBorder(BorderFactory.createEmptyBorder( 30, //top 30, //left 10, //bottom 30) //right ); pane.setLayout(new GridLayout(0, 1)); pane.add(button); pane.add(label); return pane; } public static void main(String[] args) { try { UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName()); } catch (Exception e) { } //Create the top-level container and add contents to it. JFrame frame = new JFrame("SwingApplication"); SwingApplication app = new SwingApplication(); Component contents = app.createComponents(); frame.getContentPane().add(contents, BorderLayout.CENTER); //Finish setting up the frame, and show it.
35559403.doc

5

Giáo trình Java

frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.pack(); frame.setVisible(true); } } B c ti p theo là biên d ch. Vi c biên d ch tr nên n gi n và d dàng v i Java 2 SDKs khi các gói Swing c tích h p trong phiên b n Standard Edition c a Java 2 Platform. Câu l nh nh sau: javac -deprecation SwingApplication.java Tr ng h p khi biên d ch không thành công , có th là do b n ang s d ng trình biên d ch JDK 1.1 thay vì v 1.2 ho c v 1.3 ho c ang s d ng b n beta c a Java 2 Platform. Th c thi ch ng trình s trong class path ã ch Vd: c th c hi n khi ã biên d ch thành công . C n ng d n n file th c thi: m b o là

java -classpath .;C:\java\lnfdir\newlnf.jar SwingApplication

L u ý: không c n ph i g ph n uôi m r ng .cls. trình thông d ch c a phiên b n 1.2 hay 1.3 s t ng dò tìm. 2.2 Biên d ch và th c thi ch ng trình v i JDK 1.1 ây là JDK

C ng t ng t nh v i Java 2 Platform, nh ng trình biên d ch s d ng 1.1 và JFC 1.1.
3. Th c thi các Swing Applets

vi t m t Swing Applets, tr thi u 2 applets.

c tiên là ph i th c thi

c chúng. Ph n này s gi i

Sau ây là ph n mã c a applets HelloSwingApplet.java import javax.swing.*; //This is the final package name. //import com.sun.java.swing.*; //Used by JDK 1.2 Beta 4 and all //Swing releases before Swing 1.1 Beta 3. import java.awt.*; public class HelloSwingApplet extends JApplet { // This is a hack to avoid an ugly error messag e in 1.1. public HelloSwingApplet() { getRootPane().putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE); } public void init() {
35559403.doc

6

Giáo trình Java

JLabel label = new JLabel( "You are successfully running a Swing applet!"); label.setHorizontalAlignment(JLabel.CENTER); //Add border. Should use createLineBorder, but then the bottom //and left lines don't appear -- seems to be an off-by-one error. label.setBorder(BorderFactory.createMatteBorder(1,1,2,2,Color.black)); getContentPane().add(label, BorderLayout.CENTER); } } th c thi m t Swing Applets, theo trình t các b (1) c sau: m b o là ã có trình duy t 1.1 ho c 1.2 ho c t i v Java Plug-in và chúng là nh ng phiên b n m i nh t . Tr ng h p không có các th trên, có th s d ng Applet Viewer (appletviewer).

(2) N u b n ang s d ng trình duy t 1.1 không có Java Plug-in thì c n ph i n p file Swing JAR vào trình duy t. (3) Ki m tra l i xem trình duy t c a b n ã hoàn ch nh ch a. Trong ph m vi bài này thì hình d i ây k i m ch ng cho trình duy t c a b n là ã áp ng hoàn hay hay ch a . N u trong trình duy t c a b n xu t hi n applet nh d i ây thì OK. Tr ng h p ch th y m t thay vì hai applet ho c không th y các hình nh thì trình duy t c a b n ch a th c s s n sàng.

4. Trao

i thêm v m t

ng d ng Swing

Trong ph n này, chúng ta s tìm hi u thêm thông qua ch SwingApplication. SwingApplication s hi n th c a s nh sau:

ng trình

Ph n mã c a SwingApplication.java th c hi n nh ng công vi c sau : 4.1 Importing Swing packages Dòng l nh sau s import gói Swing chính: import javax.swing.*;

35559403.doc

7

Giáo trình Java

L u ý: JFC 1.1 và Java 2 SDK v 1.2 phiên b n beta s d ng tên g i khác nhau cho gói Swing . H u h t các ch ng trình u c n import hai gói chính c a AWT là : import java.awt.*; import java.awt.event.*; 4.2 Choosing the look and feel Swing cho phép b n ch nh rõ ³look and feel´ mà ch ng trình c a b n s d ng -- Java look and feel, Windows look and feel, CDE/Motif look and feel, ... o n mã in m d i ây s ch ra cho b n cách mà SwingApplication ch nh ³look and feel´ : public static void main(String[] args) { try { UIManager.setLookAndFeel(
UIManager.getCrossPlatformLookAndFeelClassName()); } catch (Exception e) { }

...//Create and show the GUI... } 4.3 Xác l p it ng ch a m c nh M i ch ng trình c trình di n u có giao di n v i m c n gi n nh t là m t i t ng ch a thu c thành ph n c a Swing m c nh. h u h t các ng d ng, i t ng ch a Swing m c nh có th là JFrame, JDialog, ho c (cho applets) JApplet. M i i t ng JFrame s th c hi n m t c a s chính và m i JDialog s th c thi cho c a s th hai. M i i t ng JApplet th c hi n vi c hi n th c a m t applet bên trong m t c a s . Các i t ng ch a m c nh c a Swing cung c p các h tr c n thi t các thành ph n Swing th c hi n vi c v và qu n lý các hành vi . Ví d SwingApplication ch có i t ng ch a m c nh là JFrame. Khi ng i s d ng óng frame thi ng d ng s thoát. o n mã sau ây xác l p và cho hi n th frame: public class SwingApplication { ... public static void main(String[] args) { ... JFrame frame = new JFrame("SwingApplication"); //...create the components to go into the frame... //...stick them in a container named contents... frame.getContentPane().add(contents, BorderLayout.CENTER); //Finish setting up the frame, and show it. frame.addWindowListener(...); frame.pack();
35559403.doc

8

Giáo trình Java

frame.setVisible(true); } } 4.4 Xác l p buttons và labels Gi ng nh GUIs, giao di n c a SwingApplication ch a m t button và m t label. o n mã sau ây kh i t o button ó: (1) JButton button = new JButton("I'm a Swing button!"); (2) button.setMnemonic(KeyEvent.VK_I); (3) button.addActionListener(...create an action listener...); Dòng l nh (1) t o m t nút l nh v i tiêu "I'm a Swing button!". Dòng (2) xác l p key I óng vai trò t ng t nh s ki n ng i dùng kích vào nút l nh(t c là khi ng i dùng nh n Alt -i thì cùng t ng t nh kích chu t vào nút l nh). Dòng (3) ng ký vi c n m b t s ki n cho vi c kích nút l nh o n mã sau ây kh i t o và v n hành ho t ng c a label:

..//where instance variables are declared: private static String labelPrefix = "Number of button clicks: "; private int numClicks = 0; ...//in GUI initialization code: final JLabel label = new JLabel(labelPrefix + "0 "); ... label.setLabelFor(button); ...//in the event handler for button clicks: label.setText(labelPrefix + numClicks); o n mã trên n gi n, ngo i tr dòng kh i ng ph ng th c setLabelFor (). Nó xu t hi n ây gi ng nh s g i ý v k thu t h tr tr c ti p (assistive technologies) mà thông qua ó, m t label c mô t nh là m t button. 4.5 Thêm thành ph n vào các it ng ch a.

SwingApplication nhóm label và button vào trong m t i t ng ch a (JPanel) tr c khi thêm vào frame m t thành ph n khác. o n mã sau ây kh i t o m t panel: (1) JPanel pane = new JPanel(); (2) pane.setBorder(BorderFactory.createEmptyBorder(30, 30, 10, 30)); (3) pane.setLayout(new GridLayout(0, 1)); (4) pane.add(button); (5) pane.add(label); Dòng (1) dùng g i là pane. Dòng (2) t o t o m t panel, khai báo m t it ng có ki u Jpanel v i tên

ng vi n bao b c cho panel ó . giám sát t t c các thành

Dòng (3) dùng t o m t i t ng qu n lý layout ph n có trong panel s c hi n th trên m t c t .

35559403.doc

9

Giáo trình Java

Dòng (4) và (5) dùng a button và label vào trong panel . Vi c thêm button và label vào trong panel có ngh a là chúng s c i u khi n b i layout qu n lý panel ó. 4.6 Thêm ng vi n (borders) xung quanh m t thành ph n. ng vi n cho m t panel: pane.setBorder(BorderFactory.createEmptyBorder( 30, //top 30, //left 10, //bottom 30) //right ); ng vi n này n gi n ch cung c p m t vùng tr ng c a panel. Thêm 30 pixels cho top, left, và right, và 10 pixels cho bottom. Borders là tính n ng mà JPanel th a k t l p JComponent . 4.7 Handling events SwingApplication ch a 2 event handlers. M t n m b t s ki n kích vào nút l nh(action events). Cái kia n m b t s ki n óng c a s (window events). Sau ây là o n mã qu n lý các s ki n c a SwingApplication: button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { numClicks++; label.setText(labelPrefix + numClicks); } }); ... frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); 4.8 Dealing with thread issues Ch ng trình SwingApplication là m t ti n trình an toàn. B i vì, m t khi giao di n c a nó ang c hi n th (visible), thì thao tác trên giao di n c a nó ch x y ra cho m t event handler. Không th có hai ti n trình cùng truy xu t n m t GUI trong cung fm t th i i m. 4.9 Supporting assistive technologies H tr assistive technologies, m t thi t b gi ng nh c màn hình , cung c p cách th c x lý thông tin trên GUI. H tr này ã có trong h u h t các thành ph n Swing. Trong SwingApplication có m t ch c p n k thu t này: label.setLabelFor(button); Nh ã nói, vi c l y thông tin t các thành ph n Swing là i u ang c quan tâm, k thu t trên ã giúp cho công vi c này c th c hi n m t cách d dàng :
35559403.doc

o n mã sau ây s t o m t

10

Giáo trình Java

JButton button = new JButton("I'm a Swing button!"); label = new JLabel(labelPrefix + "0 "); label.setText(labelPrefix + numClicks); JFrame frame = new JFrame("SwingApplication");

35559403.doc

11

Giáo trình Java

Bài 2: Các khái ni m và ch c n ng c a Swing

Trong bài này s gi i thi u các c tr ng c a Swing và gi ng gi i các khái ni m c n thi t b n có th n m b t và s d ng các thành ph n Swing m t cách có hi u qu . Ph n cu i c a bài h c này s phân tích m t ch ng trình Swing và ây s là ph n t ng k t l i nh ng gì b n ã h c trong bài này . 1. Các thành ph n Swing và s phân c p gi i h n . Swing cung c p r t nhi u thành ph n GUI chu n nh : buttons, lists, menus, và text areas, là nh ng thành ph n mà b n s ph i h p t o nên GUI cho ch ng trình c a b n. Ngoài ra, còn có các i t ng ch a nh windows và tool bars . Trong ph n này , chúng ta s ti p t c xem xét thông qua ví d SwingApplication ã c mô t trong ph n A Quick Tour of a Swing Application's.

Ví d này s c p n m t vài thành ph n Swing th n g dùng và cách th c chúng t ng tác v i nhau trong m t GUI và c a s phân c p gi i h n. SwingApplication t o 4 thành ph n Swing th
y y y y

ng dùng nh sau:

m t frame, ho c m t c a s làm vi c chính (JFrame) m t panel, thông th m t button (JButton) m t label (JLabel) ng g i là pane (JPanel)

frame là i t ng ch a m c nh. is a top-level container. S hi n di n c a frame nh m cung c p m t vùng các thành ph n khác thi t l p s có m t c a mình trên vùng ó. Ngoài ra còn có các thành ph n khác th ng cs d ng làm i t ng ch a m c nh là dialogs (JDialog) và applets (JApplet). panel là i t ng ch a m c trung gian (intermediate container). panel nh m m c ích xác nh v trí c a button và label. Nh ng i t ng ch a m c trung gian khác còn có scroll panes (JScrollPane) và tabbed panes (JTabbedPane), chúng có nh h ng l n nhau, t ng tác v i nhau rtong giao di n c a m t ch ng trình. button và label là nh ng thành ph n c b n (atomic components), nh ng thành ph n mà không th ch a các thành ph n Swing khác AWT thông th ng, các thành ph n c b n này s là n i nh n thông tin u vào t phía ng i dùng . Swing API cung c p nhi u thành ph n c b n, bao g m combo boxes (JComboBox), text fields (JTextField), và tables (JTable).
35559403.doc

12

Giáo trình Java

Hình d i ây là s SwingApplication.

phân c p gi i h n c a các thành ph n trong ví d

Nh hình v trên, ngay c các ch ng trình Swing n gi nn nh t c ng có nhi u m c khác nhau. Nh ng bao gi g c c a s v n là i t ng ch a m c nh, n i các thành ph n Swing khác th hi n s t n t i c a mình. Mách n c: xem s phân c p c a b t k frame hay dialog nào , ch c n kích chu t vào border c a nó ch n, nh n Control-Shift-F1. M i m t i t ng ch a m c nh u gián ti p ch a m t i t ng ch a trung gian th ng c g i là content pane. Khi làm vi c, b n không c n quan tâm th nào là i t ng ch a m c nh và cái nào là i t ng ch a trung gian. Ch ng trình s t ng qu n lý cho b n . pane contains, tr c ti p ho c gián ti p ch a t t c các thành ph n s hi n th trong GUI. Riêng i v i top-level container thì có menu bar, menu bar s ng trong m t vùng c bi t n m ngoài content pane. thêm m t thành ph n vào i t ng ch a, có th dùng nhi u cách khác nhau c a ph ng th c add(). Ph ng th c add() có ít nh t 1 i s (argument) o n mã sau ây s th c hi n vi c thêm m t button và m t label vào trong panel: frame = new JFrame(...); button = new JButton(...); label = new JLabel(...); pane = new JPanel(); pane.add(button); pane.add(label); frame.getContentPane().add(pane, BorderLayout.CENTER); 2. Layout Management Các i t ng ch a s d ng layout managers xác l p kích th c và v trí c a các thành ph n ch a trong nó. Borders s nh h ng n layout c a Swing GUIs b ng cách làm cho các thành ph n l n lên. Hình d i ây hi n th GUI c a 5 ch ng trình. GUI c a chúng khác nhau là do s d ng các layout managers khác nhau xác nh kích th c và v trí c a buttons.

35559403.doc

13

Giáo trình Java

Layout management là quá trình xác nh kích th c và v trí c a các thành ph n. M c nh, m i i t ng ch a s có m t layout manager. Java platform h tr s d ng 5 layout managers thông th ng nh t : BorderLayout, BoxLayout, FlowLayout, GridBagLayout, và GridLayout. Nh ng layout managers c thi t k hi n th a thành ph n trong cùng m t th i i m. Và l p th 6, CardLayout, là m t tr ng h p c bi t. Nó cs d ng k t h p các layout managers v i nhau.
Xác l p Layout Manager

B n có th d dàng thay i m t layout managers tr thành m t container s d ng. n gi n là ch c n g i ph ng th c setLayout. o n mã sau ây s d ng BorderLayout: JPanel pane = new JPanel(); pane.setLayout(new BorderLayout());
M t vài g i ý v Component (Providing Hints about a Component)

Ta có th s d ng các ph ng th c sau tùy bi n kích th c và v trí c a các thành ph n: setMinimumSize, setPreferredSize, và setMaximumSize, ho c có th xây d ng các l p con c a các thành ph n khai thác các ph ng th c nh : getMinimumSize, getPreferredSize, và getMaximumSize. Bên c nh vi c cung c p các tùy bi n v kích th c, ta c ng còn có th cung c p thêm các tùy bi n v vi c canh ch nh, g m các ph ng th c sau: setAlignmentX và setAlignmentY, getAlignmentX và getAlignmentY methods.
How Layout Management Occurs

Ví d sau ây mô t trình t quá tr ình hi n th c a m t frame (JFrame). 1. Khi GUI c xây d ng, JFrame s g i ph ng th c pack. Vi c ch nh này s b o m frame xu t hi n úng v i kích th c mà nó ã c xác l p tr c ó. 2. To find the frame's preferred size, the frame's layout manager adds the size of the frame's edges to the preferred size of the component directly
35559403.doc

14

Giáo trình Java

contained by the frame. This is the sum of the preferred size of the frame's content pane, plus the size of the frame's menu bar, if any. 3. The content pane's layout manager is responsible for figuring out the content pane's preferred size. By default, this layout manager is a BorderLayout object. However, let's assume that we replace it with a GridLayout object that's set up to create two columns, as in the bottom right of the preceding snapshot. The interesting thing about grid layout is that it forces all components to be the same size, and it tries to make them as wide as the widest component's preferred width and as high as highest one's preferred height. First, the grid layout manager queries the content pane for its insets -- the size of the content pane's border, if any. Next, the grid layout manager queries each component in the content pane for its preferred size, noting the largest prefer red width and largest preferred height. Then it calculates the content pane's preferred size. 4. When each button is asked for its preferred size, the button first checks whether the user specified a preferred size. If so, it reports that size. If not, it queries its look and feel for the preferred size. 3. Event Handling Event handling th hi n vi c ch ng trình ph n h i các yêu c u t phía bên ngoài, ví d nh vi c ng i dùng nh n phím chu t . Ch ng trình Swing s th c hi n t t c các thao tác và n m b t các s ki n (event handling) b ng cách th c hi n ti n trình c a s ki n. M i khi ng i dùng nh n phím hay kích chu t , thì m t s ki n x y ra. B t k i t ng nào cùng u c gán b i m t s ki n. Các thành ph n Swing có th t o ra nhi u ki u s ki n khác nhau. B ng sau ây li t kê m t vài ki u s ki n: Hành ng Ki u Listener User kích vào nút l nh, nh n phím Spacebar khi ang làm vi c trong text field, ho c kích ch n vào menu ActionListener item User óng m t frame (main window) WindowListener User nh n m t nút chu t trong khi ang rê chu t trên MouseListener m t thành ph n MouseMotionList User di chuy n chu t trên m t thành ph n ener ComponentListe Thành ph n hi n th ner Thành ph n l y tr ng thá i c a keyboard FocusListener ListSelectionList Vi c ch n l a trong Table ho c list có thay i ener M i s ki n u c i di n b i m t thông tin v s ki n c ng nh nh n d ng
35559403.doc

i t ng và i t ng ó cung c p c n i phat ra s ki n. Ngu n c a
15

Giáo trình Java

s ki n thông th ng là các thành ph n, nh ng nh ng ki u i t ng khác c ng có th là ngu n c a s ki n. Hình sau ây minh ho cho v n này .

Caption: Multiple listeners can register to be notified of events of a particular type from a particular source.
Cách th c thi m t Event Handler (How to Implement an Event Handler)

M i event handler òi h i có 3 b

c nh sau:

1. Trong ph n khai báo cho l p event handler , xác nh rõ m i l p s th c thi m t listener interface ho c k th a m t l p mà l p ó th c thi m t listener interface. Ví d : 2. 3. public class MyClass implements ActionListener {

ng ký s hi n di n c a l p event handler nh là m t listener trên m t ho c nhi u thành ph n. Ví d : 4. ss); someComponent.addActionListener(instanceOfMyCla

5. Th c thi nh ng ph 6. 7. 8.

ng th c trong listene r interface. Ví d :

public void actionPerformed(ActionEvent e) { ...//code that reacts to the action... }

Hãy xem xét cách th c m t nút l nh (JButton) n m b t s ki n kích chu t. xác nh khi nào thì ng i dùng kích chu t lên nút l nh (ho c dùng các phím nóng) thì m t ch ng trình ph i có i t ng th c thi giao di n ActionListener. Ch ng trình ph i ng ký i t ng ó nh là m t action listener trên nút l nh (ngu n c a s ki n) b ng cách s d ng ph ng th c addActionListener. Khi user kích lên nút l nh, nút l nh s phát ra m t hành vi c a s ki n. ây là yêu c u c a ph ng th c actionPerformed. Trong ph ng th c này, tham s s là m t i t ng ActionEvent và tham s này s cung c p thông tin v s ki n và ngu n c a s ki n.

Caption: Khi user vào nút l nh, action listeners c a nút l nh c phát ra.
Ti n trình và Event Handling (Threads and Event Handling)

Mã c a event-handling x y ra trong m t ti n trình n hay còn g i là eventdispatching thread. i u này nh m m b o là m i event handler hoàn thành
35559403.doc

16

Giáo trình Java

vi c th c hi n tr c khi m t event handler x y ra. ví d minh ho trên, ph ng th c actionPerformed c x l trong m t ti n trình n . 4. Painting Painting ngh a là v các thành ph n trên màn hình. M c d u vi c tùy ch n các thành ph n c th c hi n m t cách d dàng, nh ng h u h t các ch ng trình u b làm ph c t p lên b ng cách tùy ch n ng vi n cho các thành ph n.
Cách làm vi c c a Painting (How Painting Works)

Khi m t Swing GUI c n v l i giao di n c a chính nó, ho c khi c n làm t i nh ng i u ch nh v tr ng thái c a ch ng trình , nó s kh i ng thành ph n m c cao nh t (top-level component) c n c v l i và làm vi c d n xu ng theo lu ng phân c p. Quá trình x lý này c th c hi n b i h th ng AWT nhàm làm cho ch ng trình có v hi u qu và thích ng h n . Các thành ph n Swing có th v l i chính nó b t k khi nào c n thi t . Khi g i ph ng th c setText trên m t thành ph n, thành ph n ó s t ng v l i chính nó, thay i kích th c,« C ng gi ng nh event -handling, painting c ng c th c hi n trong m t ti n trình n. Trong khi m t s ki n ang x y ra thì quá trình v l i không c th c hi n. Quá trình v l i các thành ph n s không b ng t qu ng b i các s ki n khác .
Ví d minh ho v Painting (An Example of Painting)

minh ho cho quá trình painting , ta s d ng l i ch SwingApplication. Hình d i là giao di n c a SwingApplication:

ng trình

S

phân c p:

Khi GUI c a SwingApplication 1.
35559403.doc

c v , quá trình ó x y ra nh sau: c tiên.
17

it

ng ch a m c

nh, JFrame, s v l i nó tr

Giáo trình Java

2. Các i t ng ch a trung gian, tr Sau ó s là JPane.

c h t là v l i background, ch a nó. ng vi n và sau

3. JPanel tr c h t s v l i background, sau ó là cùng là các thành ph n con ch a trong nó. 4.

v l i, JButton v n n c a nó, sau ó là dòng v n b n c a chính nó .

5. JLabel v l i v n b n c a nó . i u này có ngh a là, các thành ph n s v l i chính b n thân nó tr c khi nó i u khi n các thành ph n ch a trong nó v l i. Hình sau ây minh ho nh ng thành ph n th a k t JComponent và v l i chính b n thân nó : 1. background 2. custom 3. border 4. children (if opaque) painting (if any) (if any) (if any)

5. Threads and Swing N u làm vi c các thành ph n mà nh ng thành ph n ó ph thu c ho c nh h ng n tr ng thái c a nó, ta c n ph i th c hi n chúng trong m t ti n trình n. Tuy nhiên, nh ng ch ng trình khác c n s d ng ph ng th c invokeLater th c hi n vi c g i cá thành ph n có liên quan trong ti n trình y. N u m t ch ng trình t o ra và ch làm vi c trên GUI c a chính nó, thì không c n quan tâm v ti n trình. Ví d , ch ng trình là m t applet, nó s m b o an toàn khi l u c u trúc c a nó trong ph ng th c init. Th m chí, khi ch ng trình là m t ng d ng nh d i ây, thì v n m b o c s an toàn nói trên : //Thread-safe example public class MyApplication { public static void main(String[] args) { JFrame f = new JFrame(...); ...//Add components to the frame here... f.pack(); f.setVisible(true); //Don't do any more GUI work here. } ... //All manipulation of the GUI -- setText, getText, etc. -//is performed in event handlers such as actionPerformed(). ... }
35559403.doc

18

Giáo trình Java

6. Nh ng tính n ng và khái ni m khác c a Swing Swing cung c p nhi u tính n ng . R t nhi u tính n ng c cung c p b i JComponent class. M t vài tính n ng thú v s không c c p n trong bài h c này nh icons, actions, công ngh Pluggable Look & Feel, assistive technologies, và separate models.
6.1 Nh ng tính n ng c a Jcomponent (Features that JComponent Provides)

Ngo i tr i t ng ch a m c nh, t t c các thành ph n khác b t u b ng ký t J u c th a k t l p Jcomponent. H u h t các thành ph n u có các tính n ng chung nh tooltips và c u hình v giao di n (look and feel). Ngoài ra, chúng còn th a k nhi u ph ng th c ti n l i khác n a .
6.2 Icons

Nhi u thành ph n Swing, t bi t là button và label, có th hi n th hình nh. Ta có th ch nh cho các hình nh này nh là các i t ng icon
6.3 Actions

V i i t ng Action, Swing API cung c p nh ng h tr c bi t cho vi c chia x d li u và tr ng thái gi a hai ho c nhi u thành ph n phát ra các s ki n hành ng. Ví d , khi ta có m t button và m t menu item cùng m t ch c n ng, lúc os c n cân nh c vi c s d ng i t ng Action xác nh v n b n, icon và tr ng thái c a hai thành ph n.
6.4 Support for Assistive Technologies

Assistive technologies such as screen readers can use the Accessibility API to get information from Swing components. Because support for the Accessibility API is built into the Swing components, your Swing program will probably work just fine with assistive technologies, even if you do nothing special. With very little extra effort, however, you can make your program function even more smoothly with assistive technologies, which might well expand its market. See How to Support Assistive Technologies for details.
7. Phân tích m t ch ng trình Swing

Bao g m m t ng d ng nh v Swing v i tên g i là Converter s mô t cách m t ch ng trình Swing làm vi c và m i quan h g n k t nhau gi a các o n mã trong ch ng trình. Converter là m t ng d ng dùng chuy n i n v o l ng gi a hai h th ng met và U.S units. ch y c ng d ng này thì ph i biên d ch các t p tin sau: Converter.java, ConversionPanel.java, ConverterRangeModel.java, DecimalField.java, FollowerRangeModel.java,FormattedDocument.java và Unit.java. Sau ây là hình nh minh ho v giao di n c a Converter:

35559403.doc

19

Giáo trình Java

Trong các bài h c sau, chúng ta s tìm hi u chi ti t v các tính n ng, khái ni m v Swing. Ch c ch n s còn nhi u thú v ang ch i chúng ta

35559403.doc

20

Giáo trình Java

Bài 3: S d ng các tính n ng khác c a Swing Bài h c này h
1. Cách s

ng d n cách s d ng các tính n ng khác c a Swing .

d ng Actions

V i i t ng Action, ta có th s p x p và qu n lý các tr ng thái c a hai ho c nhi u thành ph n t o ra s ki n c a hành vi. Ví d , b n có th s d ng Action t o ra và qu n lý m t button trên thanh công c , m t menu bi u t ng cùng th c hi n m t ch c n ng. Sau ây là ví d c a vi c s d ng Action t o ra m t button trên thanh công c và m t menu item cùng th c hi n m t ch c n ng : Action leftAction = new <a class that implements Action> (...); JButton button = toolBar.add(leftAction); JMenuItem menuItem = mainMenu.add(leftAction); i v i button hay menu item, có c nh ng h u ích th c s c a vi c s d ng Action, ta ph i t o thành ph n s d ng ph ng th c add(Action) c a JToolBar, JMenu, ho c JPopupMenu. M c nh, không có hàm API nào t n t i bên trên addActionListener(ActionListener) k t n i m t Action v i m t thành ph n khác ang t n t i th c s . t o m t i t ng Action, nói chung là ta ph i t o m t l p con c a l p AbstractAction và th c thi nó. trong l p con này, ta cho th c hi n ph ng th c actionPerformed tác ng ng c tr l i m t cách tho áng khi hành vi s ki n x y ra. Sau ây là ví d c a vi c t o và th c hi n l p con c a l p AbstractAction: leftAction = new AbstractAction("Go left", new ImageIcon("images/left.gif")) { public void actionPerformed(ActionEvent e) { displayResult("Action for first button/menu item", e); } }; Hình d n ng. i ây là demo ng d ng c a vi c s d ng Action th c hi n ba tính

ây là nh ng gì nhìn th y khi menu "Go left" tr nên disabled:

35559403.doc

21

Giáo trình Java

o n mã c a "Go left" action: boolean selected = ...//true if the action should be enabled; //false, otherwise leftAction.setEnabled(selected); Sau khi t o ra thành ph n s d ng Action, ta có th tùy bi n chúng theo ý thích c a mình. Ví d nh khi mu n thêm vào dòng tooltip c a m t button , ho c tùy bi n vi c xu t hi n hay bi n m t c a cá thành ph n b ng cách thêm vào , xoá i các icon, dòng v n b n: button = toolBar.add(leftAction); button.setText(""); //an icon-only button button.setToolTipText("This is the left button"); menuItem = mainMenu.add(leftAction); menuItem.setIcon(null); //arbitrarily chose not to use icon in menu
The Action API

B ng sau ây li t kê nh ng ph ng th c và contructors th ng dùng các Action. Các hàm API s d ng i t ng Action c chia thành hai lo i nh sau:
y y

T o và s d ng m t Action T o m t thành ph n i u khi n Action (Action-Controlled Component)

Creating and Using an Action Constructor or Method Purpose AbstractAction() T o m t i t ng Action. Thông qua các tham s AbstractAction(String) c a ph ng th c hay Contructors, có th xác l p AbstractAction(String, v n b n hay icon trong thành ph n y. Icon) Xác l p hay nh n bi t cá thành ph n có nh n c tác ng hay không. Thông qua ph ng th c void setEnabled(false), vô hi u t t c các tác ng lên setEnabled(boolean) các thành ph n. T ng t nh v y, s d ng boolean isEnabled() ph ng th c setEnabled(true) tác ng l i hành vi c a các thành ph n. Creating an Action-Controlled Component Method Purpose
35559403.doc

22

Giáo trình Java

JMenuItem add(Action) T o m t i t ng JMenuItem và t chúng vào JMenuItem insert(Action, int) trong menu hay popup menu. (in JMenu and JPopupMenu) JButton add(Action) T o m t i t ng Jbutton và t chúng lên thanh (in JToolBar) công c .
2. Th nào là k thu t h tr Assisive(Support Assistive Technologies)

Các thành ph n Swing h tr k thu t tr giúp . Ch ng trình c a b n s c h tr t t h n. Ví d nh dòng tooltip s hi n lên ch c n ng c a m t nút l nh nào ó khi ta di chuy n chu t lên nút l nh ó .

3. Cách s

d ng các

ng vi n(Border)

Borders s em l i cho chúng ta nhi u thu n l i trong vi c v các ng th ng , tiêu hay các vùng tr ng c a m t thành ph n . Trong các ví d c a ph n này có s d ng r t nhi u border. ây, chúng ta s tìm hi u cách thêm m t border vào b t k thành ph n JComponent nào.
4. Cách s d ng Icons

Nhi u thành ph n Swing có th hi n th icons (JLabel và JButton). Th icons là tr ng h p cá bi t c a ImageIcon class.

ng thì

M t vài thành ph n Swing nh JLabel và JButton, có th c trang trí b i m t icon. Icon là m t i t ng g n k t ch t ch v i giao di n Icon. Swing cung c p cho giao di n Icon cách th c hi n r t t bi t và hi u qu v m t Icon t g m t t p tin nh có d ng th c GIF ho c JPEG. Hình d label: i ây minh ho m t ng d ng s d ng m t Icon trang trí cho hai

Trong ph n mã c a ch ng trình, câu l nh (1) dùng t o icon s d ng m t icon, câu l nh (2) và (3) gán icon y vào trong hai label :: (1) ImageIcon icon = new ImageIcon("images/middle.gif", "a pretty but meaningless splat"); ... (2) label1 = new JLabel("Image and Text", JLabel.CENTER);
35559403.doc

icon,
23

Giáo trình Java

... (3) label3 = new JLabel(icon); Tham s th nh t trong ImageIcon constructor xác nh t p tin nh n p lên, ph n này ph i ý n ng d n t i th m c có ch a t p tin class . Tham s th hai dùng mô t v icon y, gi ng nh ph n tooltip c a các ng d ng mà chúng ta v n th ng th y. Nói chung, các applet n p hính nh t máy tính, n i ph c v cho applet y. Có hai lý do làm nh v y, th nh t là không tin t ng khi các applet c các t p tin h thông t máy nó ang ch y. Th hai là k t h p các l p c a applet v i t p tin d li u v i nhau . n p m t hình nh t server, m t applet ph i s d ng URL nh o n mã trong ví d d i ây : public class SomeClass extends JApplet ... { protected String leftButtonFilename = "images/left.gif"; ... public void init() { ... URL leftButtonURL = getURL(leftButtonFilename); ... leftButtonIcon = new ImageIcon(leftButtonU RL, "an arrow pointing left"); ... } ... protected URL getURL(String filename) { URL codeBase = getCodeBase(); URL url = null; try { url = new URL(codeBase, filename); } catch (java.net.MalformedURLException e) { System.err.println("Couldn't create image: " + "badly specified URL"); return null; } return url; } ... }
y

V i m i image icon, nó s d ng m t i t ng image ch a d li u c a hình nh và i t ng MediaTracker c chia s cho t t c các icon trong cùng m t ch ng trình .

Xác

nh hình nh ngu n (Specifying the Image Source)

Th ng thì d li u c a m t hình nh xu t phát t m t t p tin hình nh. Có th xác nh n i l u tr c a t p tin thông qua tên t p tin ho c s d ng i t ng URL. i v i ng d ng, tên t p tin ho c URL u có liên quan n th m c ch a ch a t p tin .class c a ng d ng ho c là ng d n. ch nh m t URL
35559403.doc

24

Giáo trình Java

liên quan n ng d n c a ng d ng , ta có th s getSystemResource nh ví d d i ây:

d ng ph

ng th c

ImageIcon icon = null; URL iconURL = ClassLoader.getSystemResource("images/middle.gif"); if (iconURL != null) { icon = new ImageIcon(iconURL, "a beautiful yet meaningless icon"); } Ph ng th c getSystemResource s dò tìm trong th m c và t p tin JAR trong ng d n c a ch ng trình, tr v URL ngay khi nó tìm th y. Ví d , khi ta a vào ng d n c a ng d ng t p tin jar có tên icons .jar, n u t p tin JAR có ch a images/middle.gif, thì d at khoát, ng d n s tr v m t URL xác nh cho images/middle.gif. Tuy nhiên, có th là URL ó không có b t c liên quan nào v t p tin icons.jar.

The Image Icon API

B ng sau ây li t kê nh ng c u trúc và ph ng th c s d ng thông th ng c a ImageIcon. constructors and methods. L u ý là ImageIcon không có ngu n g c t JComponent hay th m chí là t Component. Setting, Getting, and Painting the I mage Icon's Image Method or Purpose Constructor ImageIcon() ImageIcon(byte[]) ImageIcon(byte[], String) T o m t ImageIcon instance, kh i t o nó ch a hình ImageIcon(Image) nh ã c xác l p. Tham s th nh t ch ra ngu n c a ImageIcon(Image, hình nh nh image, s byte, tên t p tin, hay URL. T ó String) hình nh s c n p lên. Ngu n c a hình nh ph i có ImageIcon(String) d ng th c file c h tr b i l p java.awt.Image có ImageIcon(String, uôi là GIF ho c JPEG. String) ImageIcon(URL) ImageIcon(URL, String) void Xác l p ho c l y image hi n th b i image icon. setImage(Image) Image getImage()
35559403.doc

25

Giáo trình Java

nh c a icon trong vùng ho ã c ch nhPaint the image icon's image in the specified graphics context. You would do this only if you're void implementing a custom component that performs its own paintIcon(Compone painting. The Component object is used as an image nt, Graphics, int, observer. You can rely on the default behavior provided int) by Component class and pass in any component. The two int argments specify the x and y coordinates, respectively. Setting or Getting Information about the Image Icon Method Purpose void setDescription(Stri Set or get a description of the image. This description is ng) intended for use by assistive technologies. String getDescription() int getIconWidth() Get the width or height of the image icon in pixels. int getIconHeight() Watching the Image Icon's Image Load Method Purpose void setImageObserver(ImageOb Set or get an image observer for the image server) icon. ImageObserver getImageObserver() Get the loading status of the image icon's image. The set of values returned by this int getImageLoadStatus() method are defined by MediaTracker.
5. S d ng ti n trình(Threads)

V

S d ng ti n trình là m t công vi c khó kh n . Do ó n u có th c thì b n nên tránh ph n này. Tuy nhiên Thread có th giúp c i ti n ch ng trình c a b n b ng cách qu n lý s th c thi. Nguyên t c u tiên khi s d ng Threads có th r t khó s d ng debug ch ng trình. tránh tr quan tâm ngay t u r ng m i ti k m t thành ph n Swing nào . threads là: tránh dùng chúng n u nh có th . và chúng có th gây khó kh n khi chúng ta ng h p b ình tr c a ch ng trình , c n ph i n trình c t o ra không kêu g i th c thi b t

M c dù nguy hi m, nh ng threads r t cso giá tr khi ta s d ng chúng m t cách c n th n. Ta có th c i thi n vi c th c hi n ch ng trình. ôi khi, m t vài ti n trình làm n gi n mã ho c c u trúc c a m t ch ng trình. Sau ây là m t vài tình hu ng khi s d ng ti n trình:
y

To move a time-consuming initialization task out of the main thread, so that the GUI comes up faster. Examples of time-consuming tasks
26

35559403.doc

Giáo trình Java

include making extensive calculations and blocking for network or disk I/O (loading images, for example).
y

To move a time-consuming task out of the event-dispatching thread, so that the GUI remains responsive. To perform an operation repeatedly, usually with some predetermined period of time between operations. To wait for messages from other programs.

y

y

N u t o m t thread, c n ph i tránh nh ng nguy hi m khi th c thi m t ti n trình v i các l p ti n ích nh SwingWorker hay Timer . i t ng SwingWorker t o m t thread th c thi m t qui trình x lý v th i gian. Sau khi qui trình hoàn thành, SwingWorker cung c p m t vài tùy ch n th c hi n vi c g i i m t s ki n. i t ng Timer th c thi m t thread và sinh ra m t ho c nhi u hành vi s ki n sau khi xác nh c l p l i.
6. S d ng Timers

V i l p Timer, b n có th cho th c hi n m t ti n trình c a vi c th c thi m t hành ng sau m t kho ng th i gian xác nh và l p l i hành vi y . Có hai cách
y

th c hi n Timer:

Th c hi n m t tác v , v i th i gian l p l i c xá c nh. Ví d , tool tip manager s d ng timers quy t nh khi nào thì hi n th và khi nào thì t t nó i. Th c hi n vi c l p it i l p l i m t tác v .

y

Trong ví d d i ây s d ng c a m t tác v .

ng timer

th hi n ti n trì nh làm vi c

Và ây là o n mã c a ch ng trình ProgressBarDemo.java. public final static int ONE_ SECOND = 1000; ... timer = new Timer(ONE_SECOND, new ActionListener() { public void actionPerformed(ActionEvent evt) { //...Perform a task... } }); Khi user nh n vào nút Start, ch ng trình kh i ng timer :
35559403.doc

27

Giáo trình Java

timer.start(); Và khi tác v hoàn thành, action listener c a timer s d ng timer: if (/* task is done */) { ... timer.stop(); ... } The Timer API B ng sau ây li t kê nh ng c u trúc và ph ng th c c a Timer. Các hàm API v s d ng timers chia thành hai lo i nh sau:
y y

T o và kh i

ng Timer

Ch y m t Timer

Creating and Initializing the Timer Method or Purpose Constructor T o m t timer. Tham s int ch rõ th i gian d ng (milliseconds) gi a hai hành vi s ki n. S d ng setDelay thay i tr . Tham s th hai là m t action listener, là Timer(int, m t constructor dùng nh n bi t v i m t timer . Ngoài ra, ActionListener) còn có th ng ký action listeners v i addActionListener và g b chúng b ng removeActionlistener. void setDelay(int) Xác l p ho c l y s milliseconds. int getDelay() void setInitialDelay(int Xác l p ho c l y s milliseconds ch tr c khi b t u ) hành vi s ki n th nh t . int getInitialDelay() void setRepeats(boole Xác l p ho c ch ra timer có l p l i hay không. M c nh có giá tr true. G i setRepeats(false) kh i u cho m t an) timer kh i ng và k t thúc m t hành. boolean isRepeats() void setCoalesce(bool Xác l p ho c ch ra timer có liên t c hay không. G i m t hành vi s ki n vào m t hành vi s ki n n . M c nh có ean) gái tr true. boolean isCoalesce() Running the Timer Method Purpose void start() Kh i ng timer. restart còn có th thoát b t k m t hành vi c g i t i. void restart() s ki n nào D ng ho t ng c a m t timer. void stop() Ki m tra xem có timer. boolean
35559403.doc

28

Giáo trình Java

isRunning()

35559403.doc

29

Giáo trình Java

Bài 4: B trí các thành ph n bên trong các

it

ng ch a

Bài h c này s h ng d n b n cách qu n lý vi c bày trí mà Java Platform cung c p, cách s d ng v trí tuy t i.
1. S d ng Layout Managers

Ph n này cung c p các qui t c t ng quan và chi ti t l nh trong vi c s d ng vi c qu n lý b trí mà Java platform cung c p.
a. S d ng Layout Managers S d ng BorderLayout Sau ây là m t Applet cho th y BorderLayout làm vi c nh th nào . setLayout(new BorderLayout()); setFont(new Font("Helvetica", Font.PLAIN, 14));

add("North", new Button("North")); add("South", new Button("South")); add("East", new Button("East")); add("West", new Button("West")); add("Center", new Button("Center")); Quan tr ng: khi thêm m t thành ph n vào m t Container s d ng BorderLayout, b n nên dùng ph ng th c add() hai thông s , và thông s th nh t ph i là "North", "South", "East", "West", ho c "Center". N u b n s d ng ph ng th c add()m t thông s hay b n không xác l p thông s th nh t thì thành ph n ó s không hi n th . Theo m c nh, BorderLayout không t kho ng tr ng gi a các thành . Mu n v y, b n ph i xác l p nó b ng cách dùng c u trúc sau : public BorderLayout(int horizont alGap, int verticalGap) S d ng CardLayout Sau ây là m t Applet cho th y CardLayout làm vi c nh th nào. //Where instance variables are declared: Panel cards; final static String BUTTONPANEL = "Panel with Buttons"; final static String TEXTPANEL = "Panel with TextField"; //Where the container is initialized: cards = new Panel(); cards.setLayout(new CardLayout()); ...//Create a Panel named p1. Put buttons in it . ...//Create a Panel named p2. Put a text field in it. cards.add(BUTTONPANEL, p1); cards.add(TEXTPANEL, p2); Khi b n thêm m t thành ph n vào m t Container mà có s d ng CardLayout , b n ph i s d ng ph ng th c add() hai thông s : add(String name, Component comp). Thông s th nh t có th b t kì chu i nào nh n ra thành ph n c thêm vào. Sau ây là m t o n mã ví d cho ph ng th c trên :
35559403.doc

30

Giáo trình Java

//Where the container is initialized: ... //Put the Choice in a Panel to get a nicer look. Panel cp = new Panel(); Choice c = new Choice(); c.addItem(BUTTONPANEL); c.addItem(TEXTPANEL); cp.add(c); add("North", cp); ... public boolean action(Event evt, Object arg) { if (evt.target instanceof Choice) { ((CardLayout)cards.getLayout()).show(cards,(String)arg); return true; } return false; } Nh o n mã trên, b n có th s d ng ph ng th c show() c a CardLayout xác l p thành ph n hi n th hi n t i . Thông s th nh t c a ph ng th c show() là Container mà CardLayout i u khi n. thông s th hai là chu i xác nh thành ph n hi n th . Chu i này gi ng nh chu i c a thành ph n thêm vào Container. Theo sau là t t c các ph ng th c c a CardLayout mà có th cho phép ch n m t thành ph n. cho m i ph ng th c, thông s th nh t Container cho CardLayout là m t Layout Manager . public void first(Container parent) public void next(Container parent) public void previous(Container parent) public void last(Container parent) public void show(Container parent, String name) S d ng FlowLayout Sau ây là m t Applet cho th y FlowLayout ho t ng nh th nào. setLayout(new FlowLayout()); setFont(new Font("Helvetica", Font.PLAIN, 14)); add(new Button("Button 1")); add(new Button("2")); add(new Button("Button 3")); add(new Button("Long-Named Button 4")); add(new Button("Button 5")); L p FlowLayout có ba c u trúc: public FlowLayout() public FlowLayout(int alignment) public FlowLayout(int alignment, int horizontalGap, int verticalGap) thông s alignment ph i là các giá tr FlowLayout.LEFT, FlowLayout.CENTER, ho c FlowLayout.RIGHT. Thông s horizontalGap và
35559403.doc

31

Giáo trình Java

verticalGap xác nh s Pixel c gi a các thành ph n. N u b n không xác l p giá tr này, FlowLayout s m c nh giá tri 5 cho m i thông s . S d ng GridLayout Sau ây là m t Aplet cho th y GridLayout làm vi c nh th nào . //Construct a GridLayout with 2 columns and an unspecified number of rows. setLayout(new GridLayout(0,2)); setFont(new Font("Helvetica", Font.PLAIN, 14)); add(new Button("Button 1")); add(new Button("2")); add(new Button("Button 3")); add(new Button("Long-Named Button 4")); add(new Button("Button 5")); C u trúc trên cho th y l p GridLayout t o m t i t ng có hai c t và nhi u hàng. ây là m t trong hai c u trúc cho GridLayout. Sau ây là cách khai báo cho c hai c u trúc này: public GridLayout(int rows, int columns) public GridLayout(int rows, int col umns, int horizontalGap, int verticalGap) S d ng GridBagLayout Theo sau là m t vài o n l nh tiêu bi u trong m t Container có s d ng GridBagLayout. GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); setLayout(gridbag); //For each component to be added to this container: //...Create the component... //...Set instance variables in the GridBagConstraints instance... gridbag.setConstraints(theComponent, c); add(theComponent); B n có th s d ng l i m t i t ng c a GridBagConstraints cho nhi u thành ph n khác nhau, ngay c khi các thành ph n ó có s ràng bu c khác nhau. GridBagLayout rút ra m t giá tr ràng bu c và không dùng l i GridBagConstraints. B n ph i c n th n, tuy nhiên, kh i t o l i giá tr c a m t i t ng GridBagConstraints làm giá tr m c nh khi c n thi t . B n có th xác l p các giá tr sau : gridx, gridy Xác nh hàng và c t t i v trí trên bên tái c a thành ph n. H u h t c t trên bên t i có c ch gridx=0, và hàng trên cùng có a ch gridy=0. S d ng GridBagConstraints.RELATIVE (giá tr m c nh) xác nh r ng thành ph n ó ch bên ph i hay phía d i . gridwidth, gridheight xác l p s c t ho c s hàng trong vùng hi n th c a thành ph n . nh ng giá tr này xác nh s Cell mà thành ph n s d ng, không ph i s Pixel nó s d ng . M c nh là 1. S d ng GridBagConstraints.REMAINDER xác nh thành ph n ang hàng cu i cùng hay c t cu i cùng . S d ng
35559403.doc

32

Giáo trình Java

GridBagConstraints.RELATIVE xác nh b c k ti p c a thanh ph n là hàng cu i hay c t cu i cùng . fill c s d ng khi vùng hi n th c a thành ph n l n h n kich th c thành ph n òi h i quy t nh khi nào ho c thay i kích th c nh th nào . các giá tr thích h p là GridBagConstraints.NONE (m c nh), GridBagConstraints.HORIZONTAL, GridBagConstraints.VERTICAL và GridBagConstraints.BOTH. ipadx, ipady xác nh ph n ph bên trong : bao nhiêu thêm vào kích th c t i thi u c a thành ph n. giá tr m c nh là 0. Chi u r ng c a thành ph n t i thi u nh t là b ng chi u r ng t i thi u c a nó c ng v i ipadx*2. Similarly, chi u cao c a thành ph n t i thi u nh t là b ng chi u cao t i thi u c a nó c ng v i ipady*2. insets xác nh ph n ph bên ngoài c a thành ph n . m c nh, m i thành ph n không có ph n ph bên ngoài. anchor c s d ng khi thành ph n nh h n vùng hi n th quy t nh khi nào t thành ph n. gái tr thích h p là GridBagConstraints.CENTER (m c nh), GridBagConstraints.NORTH, GridBagConstraints.NORTHEAST, GridBagConstraints.EAST, GridBagConstraints.SOUTHEAST, GridBagConstraints.SOUTH, GridBagConstraints.SOUTHWEST, GridBagConstraints.WEST, và GridBagConstraints.NORTHWEST. Ví d : Sau ây là m t Applet ch cho th y GridBagLayout ho t ng nh th nào. Sau ây là m t o n l nh t o m t GridBagLayout và các thành ph n nó qu n lí protected void makebutton(String name, GridBagLayout gridbag, GridBagConstraints c) { Button button = new Button(name); gridbag.setConstraints(button, c); add(button); } public GridBagWindow() { GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); setFont(new Font("Helvetica", Font.PLAIN, 14)); setLayout(gridbag); c.fill = GridBagConstraints.BOTH; c.weightx = 1.0; makebutton("Button1", gridbag, c); makebutton("Button2", gridbag, c); makebutton("Button3", gridbag, c); c.gridwidth = GridBagConstraints.REMAINDER; //end of row
35559403.doc

33

Giáo trình Java

makebutton("Button4", gridbag, c); c.weightx = 0.0; //reset to the default makebutton("Button5", gridbag, c); //another row c.gridwidth = GridBagConstraints.RELATIVE; //next to last in row makebutton("Button6", gridbag, c); c.gridwidth = GridBagConstraints.REMAINDER; //end of row makebutton("Button7", gridbag, c); c.gridwidth = 1; //reset to the default c.gridheight = 2; c.weighty = 1.0; makebutton("Button8", gridbag, c); c.weighty = 0.0; //reset to the default c.gridwidth = GridBagConstraints.REMAINDER; //end of row c.gridheight = 1; //reset to the default makebutton("Button9", gridbag, c); makebutton("Button10", gridbag, c); }
2. T o m t Custom Layout Manager

Thay vì s d ng cách qu n lý mà Java platform cung c p, ta có th vi t m t ch ng trình qu n lý c a chính mình. Qu n lý b trí ph i th c thi LayoutManager interface, n i ch nh n m ph ng th c ph i c nh ngh a. Vi c qu n lý cách b trí có th th c thi LayoutManager2, là m t giao di n con c a LayoutManager. N m ph ng th c c th c thi là :
(1) void addLayoutComponent(String, Component) (2)void removeLayoutComponent(Component) (3)Dimension preferredLayoutSize(Container) (4)Dimension minimumLayoutSize(Container) (5)void layoutContainer(Container) public void addLayoutComponent(String name, C omponent comp) Ch c g i b ng ph ng th c add(name, component) c a Container. public void removeLayoutComponent(Component comp) G i b i nh ng ph ng th c remove() và removeAll() c a Container. public Dimension preferredLayoutSize(Container parent) G i b i ph ng th c preferredSize() c a Container, có th t g i d i m i tình hu ng. public Dimension minimumLayoutSize(Container parent) G i b i ph ng th c minimumSize() c a Container, có th t g i d i m i tình hu ng.
35559403.doc

34

Giáo trình Java

public void layoutContainer(Container parent) G i khi Container hi n th l n uis first displayed , và m i lúc nó tahy th c.
3. Làm vi c không có Layout Manager(Absolute Positioning)

i kích

If necessary, you can position components without using a layout manager. Generally, this solution is used to specify absolute sizes and positions for components. M c dù có th làm vi c mà không c n Layout Manager, b n nên dùng Layout Manager n u có th . Layout managers d thay i kích th c c a Container và i u ch nh hình d ng c a các thành ph n ph thu c vào Platform. Nó cùng có th c s d ng l b i các Container va các ch ng trình khác. n u Custom Container sè không tái s d ng, không th thay i kích th c, và hoàn toàn có th i u khi n c các thông s ph thu c vào h th ng nh Font và hình d ng các thành ph n. Ví d : public class NoneWindow extends Frame { ... private boolean laidOut = false; private Button b1, b2, b3; public NoneWindow() { super(); setLayout(null); setFont(new Font("Helvetica", Font.PLAIN, 14)); b1 = new Button("one"); add(b1); b2 = new Button("two"); add(b2); b3 = new Button("three"); add(b3); } public void paint(Graphics g) { if (!laidOut) { Insets insets = insets(); /* * We're guaranteed that insets() will return a valid Insets * if called from paint() -- it isn't valid when called from * the constructor. * * We could perhaps cache this in an ivar, but insets can * change, and when they do, the AWT creates a whole new * Insets object; the old one is invalid. */ b1.reshape(50 + insets.left, 5 + insets.top, 50, 20); b2.reshape(70 + insets.left, 35 + insets.top, 50, 20); b3.reshape(130 + insets.left, 15 + insets.top, 50, 30);
35559403.doc

35

Giáo trình Java

laidOut = true; } } ...
} 4. Gi i quy t các v n v Layout

M t vài v n thông th ng v layout mà th ng là các thành ph n hi n th quá nh ho c không hi n th . Trong ph n này s giúp chúng ta x lý nh ng v n này. Bài toán: Làm th nào xác nh c chính xác kích th c c a m t thành ph n? y u tiên, ch c ch n b n th t s mu n xác l p kích th c chính xác c a thành ph n. nh ng thành ph n chu n có kích th c khác nhau , ph thu c vao Platform mà thành ph n ó ang ch y và Font nó s d ng , vì v y thwongf ch làm theo c m giác xác nh kích th c chính xác c a các thành ph n. i v i nh ng Custom Component có kích th c xác nh, xác nh kích th c chính xác ch là c m giác ch quan . B n c n b qua các ph ng th c minimumSize() và preferredSize() c a thành ph n tr v m t kích th c úng cho thành ph n ó . thay i kích th c c a thành ph n khi thành ph n ó ang hi n th , xem bài toán ti p theo. Bài toán: Làm th nào thay i kích th c c a m t thành ph n ? y M t khi thành ph n ã hi n th , b n có th thay i kích th c c a nó b ng ph ng th c resize(). R i b n g i ph ng th c validate() Container vè l i. Bài toán: Thành ph n ang có kích th c quá nh . y Thành ph n ó có th c thi nh ng ph ng th c preferredSize() và minimumSize() hay không? N u v y, nó có tr v giá tr úng hay không? y Khi b dùng Layout manager, b n có th dùng không gian s n có hay không? Bài 5: Vi t s ki n Listeners Trong bài h c này s trình bày m t cách chi ti t làm th nào vi t m t s ki n listeners. hi u ph n này thì b n ph i có ki n th c v Event Handling .
1. M t vài ví d v Event-Handling

Các applets trong ph n này s minh ho cho các s ki n và quá trình ti n hành c a s ki n.
2. T ng quan v Writing Event Listeners

Cung c p thông tin c n thi t v t t c các ki u c a s ki n. M t trong nh ng tiêu trong ph n này là trình bày cách làm sao gi m b t công s c và s
35559403.doc

36

Giáo trình Java

không c n thi t c a vi c vi t code cho ch trong th c thi các s ki n.

ng trình b ng cách s d ng các l p

có th n m b t ph n này m t cách d dàng , xem nh b n ã có nh ng ki n th c c b n v các s ki n listener trong ph n Event Handling. Ch ng h n nh ta có th g n m t a listeners vào ngu n c a m t n s ki n. Nh ng quan tr ng h n h t là các ph ng th c event-listener s c x lý m t cách nhanh chóng. B i vì t t c các event-handling và các ph ng th c v u c th c hi n trong cung m t ti n trình . Trong ph n này, chúng ta s bàn v EventObject, m t l p con cho t t c các s ki n AWT và Swing
L y thông tin s Objects) ki n: Event Objects (Getting Event Information: Event

M i m t ph ng th c event -listener u có m t i s n, m t i t ng th a k t l p EventObject. method has a single argument -- an object that inherits from the EventObject class. M c dù i s luôn xu t phát t EventObject, v i ki u t ng quan có th th c hi n chính xác h n . Ví d nh khi n m b t s ki n c a chu t, i s cho ph ng th c này s l y t MouseEvent, m t l p con c a EventObject. L p EventObject nh ngh a m t ph ng th c r t h u ích nh sau :
Object getSource() Ph ng th c này tr v m t i t ng n m b t s ki n . Chú ý r ng ph ng th c getSource c ng tr v m t i t ng. L p Event ôi khi c ng nh ngh a m t ph ng th c gi ng nh getSource, nh ng ki u c a giá tr tr v h i b h n ch . Ví d nh l p ComponentEvent nh ngh a ph ng th c getComponent, gi ng nh getSource, tr v i t ng n m b t s ki n. Cái khác nhau ây là getComponent luôn luôn tr v m t Component. Th ng thì m t l p s ki n nào ó nh ngh a m t ph ng th c và tr v thông tin c a s ki n. Khái ni m: Low-Level Events and Semantic Events

Các s ki n có th c phân chia thành 2 lo i: low-level events và semantic events. Low-level events mô t window-system x y ra ho c d li u vào m c th p (low-level input). T t c các s ki n còn l i thu c lo i semantic event. S ki n mouse và key, c hai u là k t qu tr c ti p t phía ng i dùng, là nh ng s ki n low-level. Nh ng s ki n low-level khác bao g m component, container, focus, và window events. S ki n component cho phép thay i v trí, kích th c và s hi n th c a thành ph n. S ki n container qu n lý n m b t c thành ph n nào khi c thêm vào hay g b kh i các i t ng ch a. Focus events s báo cho bi t khi nào m t thành ph n là có ho c không keyboard focus, kh n ng nh n bi t ký t c gõ t i bàn phím . Window events giúp n m b t nh ng tr ng thái c n b n nh t c a b t k Window nào , ch ng h n nh Dialog hay m t Frame .

35559403.doc

37

Giáo trình Java

Semantic events bao g m action events, item events, và list selection events. Hành ng c a m i semantic event có th khác nhau do thành ph n . Ví d nh m t button có th n m b t s ki n khi ng i dùng kích chu t lên nó . Nh ng m t text field n m b t s ki n khi ng i dùng nh n Ret urn. S d ng Adapters and Inner Classes n m b t các s ki n

Ph n này h ng d n b n s d ng các l p adapters và inner làm gi m b t s l n x n trong o n mã c a ch ng trình b n . H u h t các giao di n AWT listener, không nh ActionListener, ch a nhi u ho c m t ph ng th c. Ví d , giao di n MouseListener ch a n m ph ng th c: mousePressed, mouseReleased, mouseEntered, mouseExited, và mouseClicked. Dù là b n ch quan tâm v nh n chu t, n u l p b n ang s d ng th c thi MouseListener thì b n ph i th c thi t t c 5 ph ng th c. Ví d : //An example with cluttered but valid code. public class MyClass implements MouseListener { ... someObject.addMouseListener(this); ... /* Empty method definition. */ public void mousePressed(MouseEvent e) { } /* Empty method definition. */ public void mouseReleased(MouseEvent e) { } /* Empty method definition. */ public void mouseEntered(MouseEvent e) { } /* Empty method definition. */ public void mouseExited(MouseEvent e) { } public void mouseClicked(MouseEvent e) { ...//Event handler implementation goes here... } } áng ti c là k t qu c a s l a ch n các ph ng th c r ng có th khó c và duy trì. giúp b n tránh c các l n x n v i nh ng ph ng th c r ng trong ch ng trình , AWT cung c p l p adapter class cho m i listener interface v i nhi u h n m t ph ng th c. s d ng adapter, b n t o m t l p con cho nó, thay vì ph i th c thi m t listener interface. /* * An example of extending an adapter class instead of * directly implementing a listener interface. */
35559403.doc

38

Giáo trình Java

public class MyClass extends MouseAdapter { ... someObject.addMouseListener(this); ... public void mouseClicked(MouseEvent e) { ...//Event handler implementation goes here... } } Gi d b n mu n vi t m t applet, và b n mu n Applet c a b n ch a vài o n mã n m b t các s ki n c a chu t. T khi ngôn ng Java khhong cho phép a th a k thì b n không th m r ng c 2 l p Applet and MouseAdapter. Gi i pháp là nh ngh a m t l p inner -- m t l p n m trong Aplet -- that extends the MouseAdapter class, //An example of using an inner class. public class MyClass extends Applet { ... someObject.addMouseListener(new MyAdapter()); ... class MyAdapter extends MouseAdapter { public void mouseClicked(MouseEvent e) { ...//Event handler implementation go es here... } } }
3. H tr Listeners c a các thành ph n Swing

Có th nói r ng lo i c a s ki n m t thành ph n có th c phân lo i b ng cách d a vào lo i c a s ki n listeners mà ta ng ký trên thành ph n ó . Ví d nh l p Component nh ngh a nhýÞng ph ng th c listener nhý sau :
y y y y y

addComponentListener addFocusListener addKeyListener addMouseListener addMouseMotionListener

Do v y, m i thành ph n h tr component , focus, key, mouse, và mousemotion listeners. Tuy nhiên, m t thành ph n kh i ng nh ng s ki n mà listeners có ngky trên nó. Ví d , m t mouse listener c ng ký trên m t thành ph n riêng bi t, nh ng thành ph n y không có listeners khác , thì thành ph n ó s kh i ng ch m i s ki n mouse events, không có các s ki n component, focus, key, or mouse-motion.
Listeners that All Swing Components Support

Vì t t c các thành ph n Swing u xu t phát t l p AWT Component, cho nên ta ph i khai báo nh ng listeners sau trên b t k thành ph n Swing nào : component listener
35559403.doc

39

Giáo trình Java

N m b t s thay i v kích th c, v trí và s hi n th c a thành ph n. focus listener N m b t các thành ph n có nh n hay không tác ng t bàn phím. key listener N m b t ng tác n phím; s ki n key ch kh i t o b i các thành ph n ang có tr ng thái m c nh c a bàn phím. mouse events N m b t s ki n kích chu t và di chuy n chu t trên thành ph n. mouse-motion events N m b t s thay i v v trí c a con tr trên thành ph n .
Các Listeners khác mà các thành ph n Swing h tr

B ng sau ây li t kê các thành ph n Swing và listeners c h tr . Trong nhi u tr ng h p, các s ki n c kh i ng tr c ti p t thành ph n . Nh ng tr ng h p khác, các s ki n c kh i ng t d li u c a thành ph n ho c t các ki u m u c ch n. Listener Component button check box color chooser combo box dialog editor pane file chooser frame internal frame X X inte rnal fra me list dat a me nu me nu key me
35559403.doc

document, chang action caret undoable item e edit X X X X X X X X X

list selection

wind oth ow er

X X X hyp erli nk

list

X

menu

menu item

X

X

X

40

Giáo trình Java

nu dra g mo use option pane password field

X

X

X pop up me nu X X X X

popup menu

progress bar radio button slider tabbed pane

X

X

table

X

tabl e mo del tabl e col um n mo del cell edit or

text area text field

X

X X

X X hyp erli nk X tree exp ansi on
41

text pane

X

X

toggle button

X

X

tree

35559403.doc

Giáo trình Java

tree will exp and tree mo del tree sele ctio n viewport (used scrollpane) by X
ng

4. Th c hi n Listeners cho các Handled Events thông th

Ph n này sã bao g m các chi ti t v ví d và thông tin c a vi c vi t nh ng s ki n listener thông th ng. Vi t m t Action Listener Khi ng i s d ng kích chu t vào Button, úp chu t vào ListItem, ch n MenuItem, ho c nh n phím trong TextField , m t s ki n s x y ra. K t qu ó là m t thông báo actionPerformed c g i i n t t c các action listener và nó ng kí v i các thành ph n có liên quan. Các ph ng th c, s ki n c a hành ng Giao di n ActionListener ch a m t ph ng th c n, và do ó nó không có l p adapter t ng ng. ây là ph ng th c ActionListener cô c: void actionPerformed(ActionEvent) M t ví d v n m b t các s ki n c a hành ng M t ví d n gi n public class Beeper ... implements ActionListener { ... //where initialization occurs: button.addActionListener(this); ... public void actionPerformed(ActionEvent e) { ...//Make a beep sound... } } Vi t m t Adjustment Listener Các s ki n Adjustment thông báo cho b n bi t s thay i giá tr trong các thành ph n. i t ng Adjustable có m t giá tr nguyên, và nó tr v các các s ki n adjustment b t c khi nào giá tr ó thay i. Ch có m t l p c a AWT th c thi Adjustable là l p Scrollbar. Có 5 lo i s ki n adjustment: track ng i s d ng hoàn toàn thay i giá tr c a thành ph n. unit increment, unit decrement
35559403.doc

42

Giáo trình Java

ng i s d ng ch bi u th s thay i nh v giá tr c a thành ph n. block increment, block decrement ng i s d ng bi u th s thay i giá tr c a thành ph n v i s l ng l n. Các ph ng th c s ki n c a Adjustment Giao di n Adjustment Listener ch a m t ph ng th c n, và vì th nó không có l p mô ph ng t ng ng. Sau ây là ph ng th c ó: void adjustmentValueChanged(Adju stmentEvent) c g i b i AWT v a sau khi thay i giá tr c a thành ph n. Ví d v Handling Adjustment Events class ConversionPanel ... implements AdjustmentListener ... { ... Scrollbar slider; ... ConversionPanel(...) { ... slider.addAdjustmentListener(this); } ... /** Respond to the slider. */ public void adjustmentValueChanged(AdjustmentEvent e) { textField.setText(String.valueOf(e.getValue())); controller.convert(this); } ... } L p AdjustmentEvent Ph ng th c adjustmentValueChanged có m t thông s : m t i t ng AdjustmentEvent. L p AdjustmentEvent nh ngh a các ph ng th c sau: Adjustable getAdjustable() Tr v thành ph n mà sinh ra s ki n ó. B n có th dùng nó thay vì dùng ph ng th c getSource. int getAdjustmentType() Tr v ki u c a adjustment c tìm th y. giá tr tr v là m t trong nh ng giá tr sau c nh ngh a trong l p AdjustmentEvent: UNIT_INCREMENT, UNIT_DECREMENT, BLOCK_INCREMENT, BLOCK_DECREMENT, TRACK. int getValue() Tr v giá tr c a thành ph n ngay sau khi adjustment c tìm th y. Vi t m t Component Listener là m t trong nh ng s k en c a thành ph n c phát ra b i i t ng Component ngay sau khi thành ph n ó m t i, làm n i, chuy n v trí ho c thay i kích th c Các ph ng th c, s ki n c a thành ph n Giao di n ComponentListener và l p mô ph ng t ng ng, ComponentAdapter, ch a 4 ph ng th c: void componentHidden(ComponentEvent) c g i b i AWT sau khi thành ph n bi n m t b i ph ng th c setVisible. void componentMoved(ComponentEvent) c g i b i AWT sau khi thành ph n di chuy n, nó quan h v i i t ng ch a nó. void componentResized(ComponentEvent) c g i b i AWT sau khi thành ph n thay i kích th c.
35559403.doc

43

Giáo trình Java

void componentShown(ComponentEvent) c g i b i AWT sau khi thành ph n xu t hi n b i ph ng th c setVisible. Ví d v Handling Component Events public class ComponentEventDemo ... implements ComponentListener { ... //where initialization occurs: aFrame = new Frame("A Frame"); ComponentPanel p = new ComponentPanel(this); aFrame.addComponentListener(this); p.addComponentListener(this); ... public void componentHidden(ComponentEvent e) { displayMessage("componentHidden event from " + e.getComponent().getClass().getName()); } public void componentMoved(ComponentEvent e) { displayMessage("componentMoved event from " + e.getComponent().getClass().getName()); } public void componentResized(ComponentEvent e) { displayMessage("componentResized event from " + e.getComponent().getClass().getName()); } public void componentShown(ComponentEvent e) { displayMessage("componentShown event from " + e.getComponent().getClass().getName()); } } class ComponentPanel extends Panel ... { ... ComponentPanel(ComponentEventDemo listener) { ...//after creating the label and checkbox: label.addComponentListener(listener); checkbox.addComponentListener(listener); } ... } L p ComponentEvent M i m t ph ng th c c a s ki n các thành ph n có m t thông s n: i t ng ComponentEvent l p ComponentEvent nh ngh a m t ph ng th c hay dùng, getComponent, tr v thành ph n mà phát ra s ki n. Vi t m t Container Listener
35559403.doc

44

Giáo trình Java

Nh ng s ki n c a Container c phát ra ngay sau khi m t thành ph n c thêm vào Container ho c chuy n i kh i Container. Các ph ng th c, s ki n c a Container Giao di n ContainerListener và l p mô ph ng t ng ng, ContainerAdapter ch a hai ph ng th c: void componentAdded(ContainerEvent) c g i sau khi m t thành ph n c thêm vào Container. void componentRemoved(ContainerEvent) c g i sau khi m t thành ph n c chuy n i kh i Container . Ví d v Handling Container Events public class ContainerEventDemo ... implements ContainerListener ... { ...//where initialization occurs: buttonPanel = new Panel(); buttonPanel.addContainerListener(this); ... public void componentAdded(ContainerEvent e) { displayMessage(" added to ", e); } public void componentRemoved(ContainerEvent e) { displayMessage(" removed from ", e); } void displayMessage(String action, ContainerEvent e) { display.append(((Button)e.getChild()).getLabel() + " was" + action + e.getContainer().getClass().getName() + "\n"); } ... } L p ContainerEvent M i ph ng th c c a Container Event có m t thông s n: i t ng ContainerEvent. L p ContainerEvent nh ngh a hai ph ng th c t h ng dùng sau: Component getChild() Tr v thành ph n c thêm hay chuy n kh i Container trong s ki n này . Container getContainer() Tar v Container sinh ra s ki n này. Vi t m t Focus Listener Các s ki n Focus c phát ra khi m t thành ph n có ho c m t i s t p trung vào nó. Các ph ng th c, s ki n c a Focus Gaio di n FocusListener và l p mô ph ng t ng ng , FocusAdapter, ch a hai ph ng th c: void focusGained(FocusEvent) c g i sau khi thành ph n có s t p trung . void focusLost(FocusEvent) c g i sau khi thành ph n m t s t p trung.
35559403.doc

45

Giáo trình Java

Ví d v Handling Focus Events public class FocusEventDemo ... implements FocusListener ... { ...//where initialization occurs window = new FocusWindow(this); ... public void focusGained(FocusEvent e) { displayMessage("Focus gained", e); } public void focusLost(FocusEvent e) { displayMessage("Focus lost", e); } void displayMessage(String prefix, FocusEvent e) { display.append(prefix + ": " + e.getSource() //XXX + "\n"); } ... } class FocusWindow extends Frame { ... public FocusWindow(FocusListener listener) { super("Focus Demo Window"); this.addFocusListener(listener); ... Label label = new Label("A Label"); label.addFocusListener(listener); ... Choice choice = new Choice(); ... choice.addFocusListener(listener); ... Button button = new Button("A Button"); button.addFocusListener(listener); ... List list = new List(); ... list.addFocusListener(listener); } } L p FocusEvent M i ph ng th c Focus Event có m t thông s n : i t ng FocusEvent. L p FocusEvent nh ngh a m t ph ng th c, isTemporary, tr v giá tr True khi s ki n m t s t p trung ó là t m th i.

35559403.doc

46

Giáo trình Java

M i thông báo thông th ng mà b n g i t i i t ng FocusEvent là getComponent ( c nh ngh a trong ComponentEvent), nó tr v thành ph n gây ra s ki n này. Vi t m t Item Listener Các s ki n c a Item c phát ra khi th c thi giao di n ItemSelectable. Các ph ng th c, s ki n c a Item Giao di n ItemListener vh có m t ph ng th c, vì v y nó không có l p mô ph ng t ng ng: void itemStateChanged(ItemEvent) c g i sau khi thay i tr ng thái c a thành ph n . Ví d v Handling Item Events public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { label.setVisible(true); } else { label.setVisible(false); } } L p ItemEvent M i ph ng th c c a Item event có m t thông s n: i t ng ItemEvent. L p ItemEvent nh ngh a các ph ng th c sau: Object getItem() Tr v Item c t p trung trong s ki n này . ItemSelectable getItemSelectable() Tar v thành ph n phát ra s ki n . int getStateChange() tr v tr ng thái m i c a Item. L p ItemEvent nh ngh a hai tr ng thái: SELECTED và DESELECTED. Vi t m t Key Listener oc phát ra khi ng i s d ng ánh phím . c bi t Key events phát ra b i i t ng mà dang c t p trung khi ng i dùng nh n ho c nh phím . Các ph ng th c s ki n c a Key Giao di n KeyListener và l p mô ph ng t ng ng, KeyAdapter, ch a ba ph ng th c: void keyTyped(KeyEvent) oc g i sau khi phím oc ánh . void keyPressed(KeyEvent) c go sau khi m t phím c n. void keyReleased(KeyEvent) c g i sau khi m t phím c nh . Ví d v Handling Key Events public class KeyEventDemo ... implements KeyListener ... { ...//where initialization occurs: typingArea = new TextField(20); typingArea.addKeyListener(this); ... /** Handle the key typed event from the text field. */ public void keyTyped(KeyEve nt e) { displayInfo(e, "KEY TYPED: ");
35559403.doc

47

Giáo trình Java

} /** Handle the key pressed event from the text field. */ public void keyPressed(KeyEvent e) { displayInfo(e, "KEY PRESSED: "); } /** Handle the key released event from the text field. */ public void keyReleased(KeyEvent e) { displayInfo(e, "KEY RELEASED: "); } ... protected void displayInfo(KeyEvent e, String s){ ... char c = e.getKeyChar(); int keyCode = e.getKeyCode(); int modifiers = e.getModifiers(); ... tmpString = KeyEvent.getKeyModifiersText(modifiers); ...//display information about the KeyEvent... } } L p KeyEvent M i ph ng th c Key Event có m t thông s n: i t ng KeyEvent. L p KeyEvent nh ngh anh ng ph ng th c th ng dùng sau : int getKeyChar() void setKeyChar(char) Nh n ho c xác l p kí t liên quan v i s ki n này . int getKeyCode() void setKeyCode(int) nh n ho c xác l p mã c a phím liên quan v i s ki n này . void setModifiers(int) xác l p t ng thái c a phím liên quan t i s ki n này int getModifiers() T v tr ng thái c a phím trong s ki n này . Vi t m t Mouse Listener Các s ki n c phát ra khi ng i s d ng dùng chu t tác ông n m t thành ph n . Các ph ng th c, s ki n c a Mouse Giao di n MouseListener và l p mô ph ng t ng ng , MouseAdapter, ch a ba ph ng th c: void mouseClicked(MouseEvent) c g i sau nkhi ng i s d ng kích ho t chu t vào m t thành ph n . void mouseEntered(MouseEvent) c g i sau khi con tr chu t n m trong a ph n c a thành ph n . void mouseExited(MouseEvent) c g i sau khi con tr chu t ra kh i a ph n c a thành ph n . void mousePressed(MouseEvent) c g i sau khi con chu t c n trên a ph n c a thành ph n .
35559403.doc

48

Giáo trình Java

void mouseReleased(MouseEvent) c g i sau khi con chu t c nh trên a ph n c a thành ph n . Ví d v Handling Mouse Events public class MouseEventDemo ... implements MouseListener { ...//where initialization occurs: //Register for mouse events on blankArea and applet (panel). blankArea.addMouseListener(this); addMouseListener(this); ... public void mousePressed(MouseEvent e) { saySomething("Mouse button press", e); } public void mouseReleased(MouseEvent e) { saySomething("Mouse button release", e); } public void mouseEntered(MouseEvent e) { saySomething("Cursor enter", e); } public void mouseExited(MouseEvent e) { saySomething("Cursor exit", e); } public void mouseClicked(MouseEvent e) { saySomething("Mouse button click", e); } void saySomething(String eventDescription, MouseEvent e) { textArea.append(eventDescription + " detected on " + e.getComponent().getClass().getName() + ".\n"); textArea.setCaretPosition(maxInt); //scroll to bottom } } L p MouseEvent M i ph ng th c Mouse Event có m t thông s n : i t ng MouseEvent. L p MouseEvent nh ngh a các ph ng th c th ng dùng sau : int getClickCount() tr v s l n nh n liên ti p c a ng i s d ng . int getX() int getY() Point getPoint() Tr v v trí c a con tr tr chu t, v trí này ph thu c vào thành ph n . boolean isPopupTrigger() tr v giá tr True khi s ki n này làm xu t hi n Popup Menu . Vi t m t Mouse Motion Listener
35559403.doc

49

Giáo trình Java

Các s ki n Mouse motion phát ra ki ng i s d ng dùng chu t di chuy n trên màn hình. Các ph ng th c, s ki n c a Mouse Motion Giao di n MouseMotionListener và l p mô ph ng t ng ng , MouseMotionAdapter, ch a hai ph ng th c: void mouseDragged(MouseEvent) c g i sau khi ng i s d ng di chuy n chu t trong khi chu t ang c nh n . void mouseMoved(MouseEvent) c g i sau khi ng i s d ng di chuy n chu t khi con chu t ch a b nh n . Ví d v Handling Mouse Motion Events ...//where initialization occurs: MyListener myListener = new MyListener(); addMouseListener(myListener); addMouseMotionListener(myListener); ... class MyListener extends MouseAdapter implements MouseMotionListener { public void mousePressed(MouseEvent e) { int x = e.getX(); int y = e.getY(); currentRect = new Rectangle(x, y, 0, 0); repaint(); } public void mouseDragged(MouseEvent e) { updateSize(e); } public void mouseMoved(MouseEvent e) { //Do nothing. } public void mouseReleased(MouseEvent e) { updateSize(e); } void updateSize(MouseEvent e) { int x = e.getX(); int y = e.getY(); currentRect.setSize(x - currentRect.x, y - currentRect.y); repaint(); } } Các ph ng th c, s ki n c s d ng b i Mouse-Motion Listeners M i ph ng th c Mouse Motion Event có m t thông s n , và nó không c g i là MouseMotionEvent! Thay vào ó, ph ng th c Mouse Motion Event s d ng i t ng MouseEvent. Vi t m t Text Listener
35559403.doc

50

Giáo trình Java

Các s ki n Text tr v sau khi chu i trong thành ph n Text có s thay i . Các ph ng th c, s ki n c a Text Giao di n TextListener ch có m t ph ng th c nên không có l p mô ph ng t ng: void textValueChanged(TextEvent) c g i sau khi chu i trong thành ph n Text thay i . Examples of Handling Text Events public class TextEventDemo ... { TextField textField; TextArea textArea; TextArea displayArea; ... //where initialization occurs: textField = new TextField(20); ... textField.addTextListener(new MyTextListener("Text Field")); textArea = new TextArea(5, 20); textArea.addTextListener(new MyTextListener("Text Area")); ... } class MyTextListener implements TextListener { String preface; public MyTextListener(String source) { preface = source + " text value changed.\n" + " First 10 characters: \""; } public void textValueChanged(TextEvent e) { TextComponent tc = (TextComponent)e.getSource(); String s = tc.getText(); ...//truncate s to 10 characters... displayArea.append(preface + s + "\"\n"); ... } } ...

ng

} L p TextEvent M i ph ng th c Text Event có m t thông s n : i t ng TextEvent. L p TextEvent nh ngh a m t ph ng th c. Ph ng th c getSource mà TextEvent th a k t EventObject, b n có th nh n c thành ph n Text liên quan n s ki n này và g i thông i p cho nó . Vi t m t Window Listener
35559403.doc

51

Giáo trình Java

Các s ki n c a Window c phát ra sau khi Window m , óng, thu nh , phóng to, ho t ng và không ho t ng . Các ph ng th c, s ki n c a Window Giao di n WindowListener và l p mô ph ng t ng ng , WindowAdapter, ch a các ph ng th c sau: void windowOpened(WindowEvent) c g i au khi Window c m l n u. void windowClosing(WindowEvent) c g i sau khi ng i s d ng óng Window . void windowClosed(WindowEvent) c g i sau khi Window óng l i . void windowIconified(WindowEvent) void windowDeiconified(WindowEvent) c g i sau khi Window phóng to hay thu nh . void windowActivated(WindowEvent) void windowDeactivated(WindowEvent) c g i sau khi Window ho t ng hay không ho t ng . Ví d v Handling Window Events public class WindowEventDemo ... implements WindowListener { ...//where initialization occurs: //Create but don't show window. window = new Frame("Window Event Window"); window.addWindowListener(this); window.add("Center", new Label("The applet listens to this window" " for window events.")); window.pack(); } public void windowClosing(WindowEvent e) { window.setVisible(false); displayMessage("Window closing", e); } public void windowClosed(WindowEvent e) { displayMessage("Window closed", e); } public void windowOpened(WindowEvent e) { displayMessage("Window opened", e); } public void windowIconified(WindowEvent e) { displayMessage("Window iconified", e); } public void windowDeiconified(WindowEvent e) { displayMessage("Window deiconified", e); }
35559403.doc

52

Giáo trình Java

public void windowActivated(WindowEvent e) { displayMessage("Window activated", e); } public void windowDeactivated(WindowEvent e) { displayMessage("Window deactivated", e); } void displayMessage(String prefix, WindowEvent e) { display.append(prefix + ": " + e.getWindow() + newline); } ... } L p WindowEvent M i ph ng th c Window Event có m t thông s n : i t ng WindowEvent. L p WindowEvent nh ngh a m t ph ng th c, getWindow, tr v Window phát ra s ki n này.
5. T ng k t v Listener API

Ph n này This section features a quick-reference table that shows each listener, its adapter class (if any), and its methods.
6. Gi i quy t các v n v Event-Handling

If you're having some hard-to-debug problems related to handling events, you might find the solution here.

35559403.doc

53

Giáo trình Java

Bài 6: Làm vi c v i

ho

Trong bài h c này, s h ng d n b n cách hi n th v n b n, các hình, nh n gi n, s d ng API làm vi c trong JDK 1.1 và 1.2. Ngoài ra còn có ví d v vi c t t o m t thành ph n, s d ng các API t om t ng vi n hay m t icon. Các ki n th c v ho t hình s k t thúc bài h c này .
1. T ng quan v ho

Gi i thi u t ng quát v nh ng thông tin c n thi t cho vi c b t v trong các thành ph n.
2. S d ng ho nguyên b n

u th c thi vi c

Trong ph n này s h ng d n b n cách v các hình n gi n và hi n th text m t cách có hi u qu . Bao g m các ví d c a vi c s d ng các l p Graphics, Font, và FontMetrics classes.
3. S d ng hình nh

Java platform h tr hình nh nh th nào s cách n p và hi n th hình nh .
4. Th c hi n ho t c nh (Performing Animation)

c bàn b c trong ph n này và

Nhi u ch ng trình th c hi n ho t c nh, ho c là ho t hình c a chú v t Duke ang tung t ng b i l i hay ch n gi n là m t hình nh chuy n ng trên màn hình. Trong ph n này s nói v cách th c hi n hình nh ng , cách s d ng i t ng Timer th c hi n ho t c nh.
T o vòng l p cho ho t c nh v i Loop with Timer) it ng Timer(Creating an Animation

B c quan tr ng nh t t o m t ch ng trình ho t hình chính là kh i t o các framework m t cách chính xác. Ngo i tr các ho t hình th c hi n tr c ti p các áp ng cho các s ki n m r ng (ví d nh vi c ng i dùng kéo m t i t ng trên màn hình), m t ch ng trình th c hi n ho t c nh c n có m t vòng l p c a ho t hình. Minh ho cho m c này có trong các ví d AnimatorAppletTimer.java và AnimatorApplicationTimer.java. Sau ây là ph n tóm l c chung nh t c a c hai ví d . ây c ng là x n c a m t ch ng trình ho t c nh: public class AnimatorClass ... implements ActionListener { int frameNumber = -1; Timer timer; boolean frozen = false; JLabel label; //In initialization code: //From user-specified frames-per-second value, determine //how long to delay between frames.
35559403.doc

54

Giáo trình Java

... //Set up a timer that calls this object's action handler. timer = new Timer(delay, this); ... //Set up the components in the GUI. public synchronized void startAnimation() { ... timer.start(); ... } public synchronized void stopAnimation() { ... timer.stop(); ... } public void actionPerformed(ActionEvent e) { //Advance the animation frame. frameNumber++; //Request that the frame be painted. label.setText("Frame " + frameNumber); } ... //When the application's GUI appears: startAnimation(); ... }
T o chuy n ng cho m t hình Across the Screen) nh trên màn hình (Moving an Image

Cách n gi n nh t t o ho t c nh là di chuy n m t hình nh trên màn hình. Trong th gi i c a ho t c nh truy n th ng , i u này c g i là cutout animation. Có hai hình mà applet s d ng . rocketship.gif:

starfield.gif:

Và ây là giao di n c a applet. C n l u ý là click chu t lên applet.
35559403.doc

kh i

ng hay d ng applet thì
55

Giáo trình Java

This is a picture of the applet's GUI. To run the applet, click the picture. The applet will appear in a new browser window. L u ý: hình rocketship có nh n n là transparent . o n mã th c hi n ho t c nh này không m y ph c t p. Nói chung, nó c ng gi ng nh x n a ra bên trên. Thay vì s d ng m t label th c hi n ho t c nh thì nó s d ng m t thành ph n tùy bi n . Thành ph n tùy bi n ây là l p con c a JPanel nh m th c thi vi c v c hai hình nh trên: ...//Where the images are initialized: Image background = getImage(getCodeBase(), "images/rocketship.gif"); Image foreground = getImage(getCodeBase(), "images/starfield.gif"); ... public void paintComponent(Graphics g) { super.paintComponent(g); //paint any space not covered //by the background image int compWidth = getWidth(); int compHeight = getHeight(); //If we have a valid width and height for the //background image, paint it. imageWidth = background.getWidth(this); imageHeight = background.getHeight(this); if ((imageWidth > 0) && (imageHeight > 0)) { g.drawImage(background, (compWidth - imageWidth)/2, (compHeight - imageHeight)/2, this); } //If we have a valid width and height for the //foreground image, paint it. imageWidth = foreground.getWidth(this); imageHeight = foreground.getHeight(this); if ((imageWidth > 0) && (imageHeight > 0)) { g.drawImage(foreground, ((frameNumber*5) % (imageWidth + compWidth)) - imageWidth, (compHeight - imageHeight)/2, this); }
35559403.doc

56

Giáo trình Java

} Có th b n s cho r ng vi c xoá nh n n là không c nh n n nào ó. Tuy nhiên, vi c xoá hình n n ây v applet luôn luôn kh i ng vi c v tr c khi hình rocketship c n p tr c hình n n thì ta s th y nh c a ch ng trình.
Hi n thi tu n t

n thi t khi s d ng m t n c quan tâm , b i l c n p y . N u hình ng ph n khác nhau này

các hình nh (Displaying a Sequence of Images)

Trong ví d c a ph n này s cung c p nh ng b c c b n c a vi c hi n th tu n t các hình nh nó th t gi ng nh ho t c nh mà ta th ng th y . D i ây là 10 hình nh mà applet s s d ng:

T1.gif:

T2.gif:

T3.gif:

T4.gif:

T5.gif:

T6.gif:

T7.gif:

T8.gif:

T9.gif:

T10.gif:

Mã c a ví d này có trong t p tin ImageSequenceTimer.java, ví d này n gi n h n ví d v a mô t trên, ch n gi n là t o m t vòng l p hi n th th t h t hình này n hình kia thay vì di chuy n m t hình nh . D i ây là s khác bi t ó: . . .//In initialization code: Image[] images = new Image[10]; for (int i = 1; i <= 10; i++) { images[i-1] = getImage(getCodeBase(), "images/duke/T"+i+".gif"); } . . .//In the paintComponent method: g.drawImage(images[ImageSequenceTimer.frameNumber % 10], 0, 0, this); Cách khác th c hi n ví d này là dùng m t label hi n th các hình nh. Thay vì s d ng o n l nh v l i hình thì ta dùng ph ng th c setIcon thay i hình c hi n th .
C i ti n giao di n và th c hi n ho t c nh (Improving the Appearance and Performance of Image Animation)

L u ý hai vi c trong v n
y

ho t c nh

trên:

Trong khi m t b c nh ang c n p, ch ng trình s hi n th m t ph n c a toàn b b c nh, các ph n khác có th ch a c hi n th . N p m t b c nh s c n m t th i gian t S d hình hình c at ng i dài.

y

ng l p MediaTracker có th gi i quy t c v n v hi n th nh. MediaTracker còn có th gi m thi u l ng th i gian n p nh. Cách khác c i ti n th i gian n p hình là thay i d ng th c p tin nh. Trong ph n này s c p t i v n này .
57

35559403.doc

Giáo trình Java

S d ng MediaTracker n p và n p hình nh (Using MediaTracker to Download Images and Delay Image Display)

L p MediaTracker cho phép n p d li u c a m t nhóm các t p tin nh và k t thúc khi hình nh ã c n p y . Nói chung, d li u c a m t hình nh ch a c t i v khi nó c v trong l n u tiên. yêu c u d li u c a các hình nh c chu n b tr c t i v , ta có th s d ng các ph ng th c c a MediaTracker nh sau: checkID(anInt, true) ho c checkAll(true). n pd li u v m t cách ng b , s d ng ph ng th c waitForID ho c waitForAll. Ph ng th c MediaTracker s d ng ti n trình c a h th ng t i d li u v , do ó có th t ng t c c a ng truy n . ki m tra tr ng thái c a vi c n p d li u v , ta dùng ph ng th c MediaTracker statusID ho c statusAll. Cách n gi n nh t ki m tra xem d li u c a hình nh có ang c t i v hay không thì dùng ph ng th c checkID ho c checkAll. Ch ng trình MTImageSequenceTimer.java là m t ví d v vi c s d ng ph ng th c MediaTracker waitForAll và checkAll. Applet v n hi n th dòng ch "Please wait..." cho n khi t t c các hình nh u cn p y . Nh ng thay i v mã d i ây s d ng MediaTracker Nh ng s khác nhau c in m. ...//Where instance variables are declared: MediaTracker tracker;
tracker = new MediaTracker(this);

hi n th hình nh.

...//In the init method: for (int i = 1; i <= 10; i++) { images[i-1] = getImage(getCodeBase(), "images/duke/T"+i+".gif"); } ...//In the buildUI method, //which is called by init and main, //allowing us to run the sample //as an applet or an application: for (int i = 1; i <= 10; i++) { tracker.addImage(images[i-1], 0); } ...//At the beginning of the actionPerformed method: try { //Start downloading the images. Wait until they're loaded. tracker.waitForAll(); } catch (InterruptedException e) {} ...//In the paintComponent method: //If not all the images are loaded, just clear the background
35559403.doc

58

Giáo trình Java

//and display a status string. if (!tracker.checkAll()) { g.clearRect(0, 0, d.width, d.height); g.drawString("Please wait...", 0, d.height/2); } //If all images are loaded, paint. else { ...//same code as before... } T ng t c vi c n p hình nh (Speeding Up Image Loading) Cho dù có hay không s d ng MediaTracker, vi c n p hình nh s URLs (cách các applets th ng làm) luôn luôn t n nhi u th i gian. H u h gian y là kh i t o s k t n i HTTP. M i m t t p tin hình nh òi h k t n i HTTP khác nhau, và m i m t k t n i y có th tiêu t n vài giây t o. Cho nên, th i gian kéo dài là chuy n ng nhiên . d ng t th i im t kh i

Cách th c tránh xãy ra phi n ph c trên là nên t t t c các hình nh vào trong m t t p tin nh. Có th s d ng t p tin JAR th c hi n i u này .
5. Gi i quy t các v n v ho

Mô t m t vài v n này.

liên quan

n

ho , gi i pháp

gi i quy t các v n

35559403.doc

59

Giáo trình Java

Bài 7: Chuy n

i qua Swing

Trong bài này s trình bày cách th c chuy n i m t ch ng trình t AWT sang s d ng các thành ph n Swing. N u m t ch ng trình c vi t s d ng v i JDK 1.0, ngh a là thay vì s d ng h th ng các s ki n listening c gi i thi u trong JDK 1.1 thì l i s d ng các ph ng th c nh là handleEvent và action, lúc ó, i u tr c tiên là chuy n i ch ng trình s d ng h th ng các s ki n m i h n.
1. T i sao ph i chuy n i

Các thành ph n Swing cung c p cho các nhà l p trình và ng i dùng u cu i nhi u thu n ti n. Tr khi b n có m t lý do nào ó th t chính áng, còn l i thì t t c nên chuy n i sang s d ng các thành ph n Swing . The strongest reason to convert to Swing is because it offers many benefits to programmers and end users. Among them: The rich set of ready-made components means that you can easily add some snazzy features to your programs -- image buttons, tool bars, tabbed panes, HTML display, images in menu items, color choosers, ... The list goes on and on. You might be able to replace or reimplement some custom components with more reliable, extensible Swing components. Having separate data and state models makes the Swing components highly customizable, and enables sharing data between components. Swing's Pluggable Look & Feel architecture gives you a wide choice of lookand-feel options. Besides the usual platform-specific looks and feels, you can also use the Java Look & Feel, add an accessory look and feel (such as an audio "look and feel"), or use a third-party look and feel. Swing components have built-in support for accessibility, which makes your programs automatically usable with assistive technologies. The Swing components will continue to be enhanced in the future. It's reasonable to put off converting if you don't think your users will be able run Swing programs conveniently. For example, if your program is an applet and you want anyone on the Internet to be able to use it, then you have to consider how many Web surfers have browsers that can run Swing programs. As of this writing, the major browsers don't have Swing support built in; the user must add it by downloading and installing Java Plug-in . You have the choice of upgrading to Java 2 (JDK 1.2) when you convert to Swing. However, you don't need to decide right now whether to upgrade. Programs written with JDK 1.1 and Swing generally work just fine in Java 2. For information about new and improved features of Java 2, see Tables of JDK Features .
2. Chuy n
35559403.doc

i nh

th nào?
60

Giáo trình Java

Trong ph n này s phác th o v trình t các b c c a vi c chuy n i ch ng trình c a b n sang dùng các thành ph n Swing. Vi c chuy n i này c áp d ng gi ng nhau cho c ng d ng và applets , tr phi có nh ng l u ý khác. Hoàn toàn t t p khi th c hi n vi c chuy n i m t ch ng trình AWT s d ng JDK 1.1. Sau ây là trình t các b B c: ng trình s chu n b chuy n i.

c 1: L u d phòng m t b n copy c a ch

Copy t t c các t p tin c a ch ng trình, k c t p tin .java và .class. Nh ng b n copy này s h u d ng cho chung sta trong m t s tr ng h p sau : - C n tham chi u - Sau khi chuy n nhau. n ph n mã ngu n trong quá trình chuy n i, có th ch y c hai b n i di n ra .

có th so sánh gi a chúng v i

- M t vài ch ng trình ng i dùng có th ch a s n sàng nâng c p VM lên phiên b n có h tr l p Swing . Do ó, có th là t m th i s d ng ch ng trình v i AWT. B c 2: Xoá b t t c nh ng tham chi u n gói java .awt.

Trong b c này, trình biên d ch s làm vi c cho b n. th c hi n vi c này, c n vô hi u t t c các dòng import ho c các o n l nh liên quan n gói java.awt, trình bêin d ch s nh c nh m i khi ta dùng m t vài l p nàp ó c a gói AWT. Tuy nhiên, v n có m t vài l p thu c gói AWT v n dùng c, ví d nh layout managers, nh ng t t nh t thì ch ng trình c a b n không nên dùng các thành ph n c a AWT. Sau ây là m t o n l nh c n c xoá b : //import java.awt.*; or //import java.awt.Button; //temporarily remove this import import java.awt.Color; //it's OK to leave this in, since //Color isn't a component ... /*java.awt.*/Frame = new /*java.awt.*/Frame(...); Tr ng h p không có tham chi u n gói AWT , tình biên d ch s phát m t l i "not found" khi phát hi n trong ch ng trình có s d ng các thành ph n AWT . i u này giúp cho vi c chuy n i d dàng h n là ph i ng i dò t ng dòng l nh trong cái r ng mà b n v a m i t o ra. Lúc ó, ch vi c thay i các thành ph n AWT sang các thành ph n Swing m t cách d dàng. Trong b c th 9, ta s tìm hi u cách thêm vào l i các l p thu c gói AWT n u c n . Step 3: N u ch ng trình là m t applet, g b dòng l nh import java.applet.* (n u có) và b t k tham chi u nào liên quan n java .applet.Applet.
35559403.doc

//temporarily remove this import

61

Giáo trình Java

Ta không c n tham chi u n l p Applet vì Swing applet ã tr thành m t l p con c a l p JApplet c a Swing. N u ch ng trình ang s d ng AppletContext, AppletStub, ho c AudioClip thì c n ph i gi l i nh ng l p này trong gói java.applet. Sau ây là m t ví d : //import java.applet.*; //temporarily remove this import //add this if necessary

import java.applet.AppletContext; B c 4: Import the gói Swing.

Thêm dong fll nh sau ay vào ch import javax.swing.*;

ng trình .

Dòng l nh s imports các thành ph n Swing cùng v i m t s l p Swing khác . B Tr c 5: Ki m nh n m t ti n trình an toàn! c khi ti p t c, c n l u ý r ng: Although AWT is thread-safe, Swing is not.

H u h t các ch ng trình u nh ngh a các thành ph n trong các ph ng th c event-handling và painting, là nh ng ph ng th c c g i t ti n trình event dispatching. nh ngh a m t thành ph n trong nh ng ph ng th c là an toàn . Tuy nhiên, n u ch ng trình c n nh ngh a m t thành ph n b t c n i nào khác n a, ví d nh trong m t ti n trình chính sau khi GUI ã hi n th , ho c trong mã l nh, thì nh t thi t ph i làm cho nó là thread-safe. B c 6: Thay ng. i m i thành ph n AWT thành nh ng thành ph n Swing t ng

Trong nhi u tr ng h p, các thành ph n AWT và các thành ph n Swing t ng ng u t ng thích v mã l nh, ch c n thay i r t n gi n v tên g i c a các thành ph n mà thôi. Ví d nh thay i môt AWT button sang m t Swing button, ch c n th c hi n nh trong b ng d i ây: AWT Code: Button button = new Button("A Button"); button.addActionListener(this); Swing Code: JButton button = new JButton("A Button"); button.addActionListener(this); M t vài thành ph n Swing có mã ngu n không t ng thích v i thành ph n AWT t ng ng. Do ó, có m t vài thành ph n AWT ph i vi t l i mã l nh khi chuy n sang s d ng các thành ph n Swing . B c 7: Chuy n i cách g i ph ng th c add và setLayout .

35559403.doc

62

Giáo trình Java

Ch ng trình s d ng các thành ph n AWT, ta có th thêm tr c ti p các thành ph n AWT vào trong frames, dialogs, và applets. T ng t , ta c ng có th xác l p các layout manager tr c ti p vào các i t ng ch a trên. Trong tr ng h p ng c l i, khi s d ng các phiên b n Swing có ch a các i t ng trên, khi thêm các thành ph n thì g i content pane. Các ví d n gi n sau : AWT Code: frame.add(panel, BorderLayout.CENTER); Swing Code: frame.getContentPane().add(panel, BorderLayout.CENTER); Và ây là ph n chi ti t: AWT Code: frame.setLayout(new frame.add(button); frame.add(label); frame.add(textField); Swing Code: Container contentPane = frame.getContentPane(); contentPane.setLayout(new FlowLayout()); contentPane.add(button); contentPane.add(label); contentPane.add(textField); o n mã sau minh ho cách chuy n i mã c a m t applet. Chú ý r ng layout manager m c nh c a m t content pane là BorderLayout ch không ph i FlowLayout c s d ng tron g Applet. AWT Code: setLayout(new BorderLayout()); add(button, BorderLayout.NORTH); add(panel, BorderLayout.CENTER); Swing Code: Container contentPane = getContentPane(); contentPane.add(button, BorderLayout.NORTH); contentPane.add(panel, BorderLayout.CENTER); B c 8: Di chuy n mã l nh c a vi c v ra kh i các ph update.
35559403.doc

FlowLayout());

ng th c paint và

63

Giáo trình Java

V i các thành ph n Swing, vi c th c hi n painting trong mã lênh c th hi n trong ph ng th c paintComponent. Cách khác th c hi n painting là s d ng các icon chu n ho c t t o và ng vi n . N u trong ch ng trình có các l p con Frame, Dialog, ho c Applet th c thi vi c làm t i hay v thì c n ph i di chuy n các mã l nh vào trong m t thành ph n khác. Còn vi c xác nh chính xác thành ph n nào thì l i ph thu c ki u c a painting. N u m t i t ng ch a có th th c hi n m t icon thì có th thay th thành ph n ó b ng m t label. Ngoài ra, các thành ph n khác có th thay th b i các l p con c a l p Jpanel. Có th thêm các thành ph n vào các content pane c a frame, dialog, ho c applet nh ã mô t b c 7. B c 9: S d ng trình biên d ch tìm ki m các thay i c n thi t khác .

Sau khi ã ph n mã ngu n nh ã mô t các b c trên, nên s d ng trình biên d ch v a biên d ch v a ki m tra l i ch ng trình . Không nên s d ng trình biên d ch trong l n u i v i ch ng trình c a mình mà ch a có s ch nh s a nào c . Trình biên d ch giúp chúng ta các công vi c nh sau : Tìm ki m các thành ph n AWT mà chúng ta ã b sót trong quá trình chuy n i sang Swing. N u nh ta ã xoá t t c các dòng l nh tham chi u n java.awt nh b c 2 thì trình biên d ch s xu t hi n câu thông báo l i nh sau: TextEventDemo.java:23: Class Button not found Trong ph n khai báo. Button button = new Button("Clear"); ^ n th i i m này, viêc nh n d ng các l p AWT trong ch ng trình v n còn c n thi t. N u nh ta ã xoá t t c các dòng l nh tham chi u n java.awt, trình biên d ch hi n th thông báo nh sau : TextEventDemo.java:17: Class BorderLayout not found Trong ph n khai báo. BorderLayout layout = new BorderLayout(); ^ Các l p AWT có th v n còn B c 10: Ch y ch c s d ng b i Swing trong ch ng trình .

ng trình Swing.

Th c hi n gi ng nh ã mô t trong ph n biên d ch và ch y ch ng trình Swing. Ch ng trình s phát ra l i tr ng h p chúng ta không nh thêm vào hay setLayout, các l i nh sau: java.lang.Error: Do not use javax.swing.JFrame.add() use
35559403.doc

64

Giáo trình Java

javax.swing.JFrame.getContentPane().add() instead at javax.swing.JFrame.createRootPaneException(JFrame.java:333) at javax.swing.JFrame.addImpl(JFrame.java:355) at java.awt.Container.add(Container.java:212) at AppletDemo.main(AppletDemo.java:121) Quay tr l i ph n mã ngu n và i u ch nh các ph n cho phù h p. B c11: So sánh hai ch kh n ng c a Swing . ng trình Swing và AWT , c i ti n ch ng trình theo

M c dù các phiên b n c a Swing và AWT là gi ng nhau, nh ng vi c c i ti n tri t theo Swing là c n thi t. C n l u ý là có m t khác bi t, tr khi b n th c hi n vi c copy b n JDK v i t p tin swing .properties ã c xác l p, còn l i thì h u h t ch ng trình u s d ng m t look and feel m i : the Java Look & Feel. Ta có th xác l p m t look and feel khác n u mu n. Step 12: Clean up! Bây gi là lúc tinh g n ph n mã l nh .

35559403.doc

65

Sign up to vote on this title
UsefulNot useful